mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +00:00 
			
		
		
		
	Vendor/Godep updates
This commit is contained in:
		
							
								
								
									
										5
									
								
								vendor/github.com/rackspace/gophercloud/auth_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/rackspace/gophercloud/auth_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -42,6 +42,11 @@ type AuthOptions struct { | ||||
| 	// 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. | ||||
| 	// | ||||
| 	// 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 | ||||
|  | ||||
| 	// TokenID allows users to authenticate (possibly as another user) with an | ||||
|   | ||||
							
								
								
									
										35
									
								
								vendor/github.com/rackspace/gophercloud/openstack/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/rackspace/gophercloud/openstack/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -134,13 +134,17 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, options gopherc | ||||
| 		v3Client.Endpoint = endpoint | ||||
| 	} | ||||
|  | ||||
| 	// copy the auth options to a local variable that we can change. `options` | ||||
| 	// needs to stay as-is for reauth purposes | ||||
| 	v3Options := options | ||||
|  | ||||
| 	var scope *tokens3.Scope | ||||
| 	if options.TenantID != "" { | ||||
| 		scope = &tokens3.Scope{ | ||||
| 			ProjectID: options.TenantID, | ||||
| 		} | ||||
| 		options.TenantID = "" | ||||
| 		options.TenantName = "" | ||||
| 		v3Options.TenantID = "" | ||||
| 		v3Options.TenantName = "" | ||||
| 	} else { | ||||
| 		if options.TenantName != "" { | ||||
| 			scope = &tokens3.Scope{ | ||||
| @@ -148,11 +152,11 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, options gopherc | ||||
| 				DomainID:    options.DomainID, | ||||
| 				DomainName:  options.DomainName, | ||||
| 			} | ||||
| 			options.TenantName = "" | ||||
| 			v3Options.TenantName = "" | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	result := tokens3.Create(v3Client, options, scope) | ||||
| 	result := tokens3.Create(v3Client, v3Options, scope) | ||||
|  | ||||
| 	token, err := result.ExtractToken() | ||||
| 	if err != nil { | ||||
| @@ -277,6 +281,29 @@ func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.Endpoi | ||||
| 	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil | ||||
| } | ||||
|  | ||||
| // 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) { | ||||
| 	eo.ApplyDefaults("volume") | ||||
| 	url, err := client.EndpointLocator(eo) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Force using v2 API | ||||
| 	if strings.Contains(url, "/v1") { | ||||
| 		url = strings.Replace(url, "/v1", "/v2", -1) | ||||
| 	} | ||||
| 	if !strings.Contains(url, "/v2") { | ||||
| 		return nil, fmt.Errorf("Block Storage v2 endpoint not found") | ||||
| 	} | ||||
|  | ||||
| 	return &gophercloud.ServiceClient{ | ||||
| 		ProviderClient: client, | ||||
| 		Endpoint:       url, | ||||
| 		ResourceBase:   url, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| // NewCDNV1 creates a ServiceClient that may be used to access the OpenStack v1 | ||||
| // CDN service. | ||||
| func NewCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/results.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/rackspace/gophercloud/openstack/compute/v2/images/results.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -51,6 +51,8 @@ type Image struct { | ||||
| 	Status   string | ||||
|  | ||||
| 	Updated string | ||||
| 	 | ||||
| 	Metadata map[string]string | ||||
| } | ||||
|  | ||||
| // ImagePage contains a single page of results from a List operation. | ||||
|   | ||||
| @@ -25,6 +25,9 @@ type Monitor struct { | ||||
| 	// The unique ID for the VIP. | ||||
| 	ID string | ||||
|  | ||||
| 	// 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 string `json:"tenant_id" mapstructure:"tenant_id"` | ||||
|   | ||||
| @@ -74,6 +74,9 @@ type CreateOpts struct { | ||||
| 	// current specification supports LBMethodRoundRobin and | ||||
| 	// LBMethodLeastConnections as valid values for this attribute. | ||||
| 	LBMethod string | ||||
|  | ||||
| 	// The provider of the pool | ||||
| 	Provider string | ||||
| } | ||||
|  | ||||
| // Create accepts a CreateOpts struct and uses the values to create a new | ||||
| @@ -85,6 +88,7 @@ func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { | ||||
| 		Protocol string `json:"protocol"` | ||||
| 		SubnetID string `json:"subnet_id"` | ||||
| 		LBMethod string `json:"lb_method"` | ||||
| 		Provider string `json:"provider,omitempty"` | ||||
| 	} | ||||
| 	type request struct { | ||||
| 		Pool pool `json:"pool"` | ||||
| @@ -96,6 +100,7 @@ func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { | ||||
| 		Protocol: opts.Protocol, | ||||
| 		SubnetID: opts.SubnetID, | ||||
| 		LBMethod: opts.LBMethod, | ||||
| 		Provider: opts.Provider, | ||||
| 	}} | ||||
|  | ||||
| 	var res CreateResult | ||||
|   | ||||
							
								
								
									
										214
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/fixtures.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/fixtures.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,214 @@ | ||||
| // +build fixtures | ||||
|  | ||||
| package listeners | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"testing" | ||||
|  | ||||
| 	th "github.com/rackspace/gophercloud/testhelper" | ||||
| 	"github.com/rackspace/gophercloud/testhelper/client" | ||||
| ) | ||||
|  | ||||
| // ListenersListBody contains the canned body of a listeners list response. | ||||
| const ListenersListBody = ` | ||||
| { | ||||
| 	"listeners":[ | ||||
| 		{ | ||||
| 			"id": "db902c0c-d5ff-4753-b465-668ad9656918", | ||||
| 			"tenant_id": "310df60f-2a10-4ee5-9554-98393092194c", | ||||
| 			"name": "web", | ||||
| 			"description": "listener config for the web tier", | ||||
| 			"loadbalancers": [{"id": "53306cda-815d-4354-9444-59e09da9c3c5"}], | ||||
| 			"protocol": "HTTP", | ||||
| 			"protocol_port": 80, | ||||
| 			"default_pool_id": "fad389a3-9a4a-4762-a365-8c7038508b5d", | ||||
| 			"admin_state_up": true, | ||||
| 			"default_tls_container_ref": "2c433435-20de-4411-84ae-9cc8917def76", | ||||
| 			"sni_container_refs": ["3d328d82-2547-4921-ac2f-61c3b452b5ff", "b3cfd7e3-8c19-455c-8ebb-d78dfd8f7e7d"] | ||||
| 		}, | ||||
| 		{ | ||||
| 			"id": "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 			"tenant_id": "310df60f-2a10-4ee5-9554-98393092194c", | ||||
| 			"name": "db", | ||||
| 			"description": "listener config for the db tier", | ||||
| 			"loadbalancers": [{"id": "79e05663-7f03-45d2-a092-8b94062f22ab"}], | ||||
| 			"protocol": "TCP", | ||||
| 			"protocol_port": 3306, | ||||
| 			"default_pool_id": "41efe233-7591-43c5-9cf7-923964759f9e", | ||||
| 			"connection_limit": 2000, | ||||
| 			"admin_state_up": true, | ||||
| 			"default_tls_container_ref": "2c433435-20de-4411-84ae-9cc8917def76", | ||||
| 			"sni_container_refs": ["3d328d82-2547-4921-ac2f-61c3b452b5ff", "b3cfd7e3-8c19-455c-8ebb-d78dfd8f7e7d"] | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
| ` | ||||
|  | ||||
| // SingleServerBody is the canned body of a Get request on an existing listener. | ||||
| const SingleListenerBody = ` | ||||
| { | ||||
| 	"listener": { | ||||
| 		"id": "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 		"tenant_id": "310df60f-2a10-4ee5-9554-98393092194c", | ||||
| 		"name": "db", | ||||
| 		"description": "listener config for the db tier", | ||||
| 		"loadbalancers": [{"id": "79e05663-7f03-45d2-a092-8b94062f22ab"}], | ||||
| 		"protocol": "TCP", | ||||
| 		"protocol_port": 3306, | ||||
| 		"default_pool_id": "41efe233-7591-43c5-9cf7-923964759f9e", | ||||
| 		"connection_limit": 2000, | ||||
| 		"admin_state_up": true, | ||||
| 		"default_tls_container_ref": "2c433435-20de-4411-84ae-9cc8917def76", | ||||
| 		"sni_container_refs": ["3d328d82-2547-4921-ac2f-61c3b452b5ff", "b3cfd7e3-8c19-455c-8ebb-d78dfd8f7e7d"] | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| // PostUpdateListenerBody is the canned response body of a Update request on an existing listener. | ||||
| const PostUpdateListenerBody = ` | ||||
| { | ||||
| 	"listener": { | ||||
| 		"id": "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 		"tenant_id": "310df60f-2a10-4ee5-9554-98393092194c", | ||||
| 		"name": "NewListenerName", | ||||
| 		"description": "listener config for the db tier", | ||||
| 		"loadbalancers": [{"id": "79e05663-7f03-45d2-a092-8b94062f22ab"}], | ||||
| 		"protocol": "TCP", | ||||
| 		"protocol_port": 3306, | ||||
| 		"default_pool_id": "41efe233-7591-43c5-9cf7-923964759f9e", | ||||
| 		"connection_limit": 1000, | ||||
| 		"admin_state_up": true, | ||||
| 		"default_tls_container_ref": "2c433435-20de-4411-84ae-9cc8917def76", | ||||
| 		"sni_container_refs": ["3d328d82-2547-4921-ac2f-61c3b452b5ff", "b3cfd7e3-8c19-455c-8ebb-d78dfd8f7e7d"] | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| var ( | ||||
| 	ListenerWeb = Listener{ | ||||
| 		ID:                     "db902c0c-d5ff-4753-b465-668ad9656918", | ||||
| 		TenantID:               "310df60f-2a10-4ee5-9554-98393092194c", | ||||
| 		Name:                   "web", | ||||
| 		Description:            "listener config for the web tier", | ||||
| 		Loadbalancers:          []LoadBalancerID{{ID: "53306cda-815d-4354-9444-59e09da9c3c5"}}, | ||||
| 		Protocol:               "HTTP", | ||||
| 		ProtocolPort:           80, | ||||
| 		DefaultPoolID:          "fad389a3-9a4a-4762-a365-8c7038508b5d", | ||||
| 		AdminStateUp:           true, | ||||
| 		DefaultTlsContainerRef: "2c433435-20de-4411-84ae-9cc8917def76", | ||||
| 		SniContainerRefs:       []string{"3d328d82-2547-4921-ac2f-61c3b452b5ff", "b3cfd7e3-8c19-455c-8ebb-d78dfd8f7e7d"}, | ||||
| 	} | ||||
| 	ListenerDb = Listener{ | ||||
| 		ID:                     "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 		TenantID:               "310df60f-2a10-4ee5-9554-98393092194c", | ||||
| 		Name:                   "db", | ||||
| 		Description:            "listener config for the db tier", | ||||
| 		Loadbalancers:          []LoadBalancerID{{ID: "79e05663-7f03-45d2-a092-8b94062f22ab"}}, | ||||
| 		Protocol:               "TCP", | ||||
| 		ProtocolPort:           3306, | ||||
| 		DefaultPoolID:          "41efe233-7591-43c5-9cf7-923964759f9e", | ||||
| 		ConnLimit:              2000, | ||||
| 		AdminStateUp:           true, | ||||
| 		DefaultTlsContainerRef: "2c433435-20de-4411-84ae-9cc8917def76", | ||||
| 		SniContainerRefs:       []string{"3d328d82-2547-4921-ac2f-61c3b452b5ff", "b3cfd7e3-8c19-455c-8ebb-d78dfd8f7e7d"}, | ||||
| 	} | ||||
| 	ListenerUpdated = Listener{ | ||||
| 		ID:                     "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 		TenantID:               "310df60f-2a10-4ee5-9554-98393092194c", | ||||
| 		Name:                   "NewListenerName", | ||||
| 		Description:            "listener config for the db tier", | ||||
| 		Loadbalancers:          []LoadBalancerID{{ID: "79e05663-7f03-45d2-a092-8b94062f22ab"}}, | ||||
| 		Protocol:               "TCP", | ||||
| 		ProtocolPort:           3306, | ||||
| 		DefaultPoolID:          "41efe233-7591-43c5-9cf7-923964759f9e", | ||||
| 		ConnLimit:              1000, | ||||
| 		AdminStateUp:           true, | ||||
| 		DefaultTlsContainerRef: "2c433435-20de-4411-84ae-9cc8917def76", | ||||
| 		SniContainerRefs:       []string{"3d328d82-2547-4921-ac2f-61c3b452b5ff", "b3cfd7e3-8c19-455c-8ebb-d78dfd8f7e7d"}, | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // HandleListenerListSuccessfully sets up the test server to respond to a listener List request. | ||||
| func HandleListenerListSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/listeners", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
|  | ||||
| 		w.Header().Add("Content-Type", "application/json") | ||||
| 		r.ParseForm() | ||||
| 		marker := r.Form.Get("marker") | ||||
| 		switch marker { | ||||
| 		case "": | ||||
| 			fmt.Fprintf(w, ListenersListBody) | ||||
| 		case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab": | ||||
| 			fmt.Fprintf(w, `{ "listeners": [] }`) | ||||
| 		default: | ||||
| 			t.Fatalf("/v2.0/lbaas/listeners invoked with unexpected marker=[%s]", marker) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleListenerCreationSuccessfully sets up the test server to respond to a listener creation request | ||||
| // with a given response. | ||||
| func HandleListenerCreationSuccessfully(t *testing.T, response string) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/listeners", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "POST") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestJSONRequest(t, r, `{ | ||||
| 			    "listener": { | ||||
| 			        "loadbalancer_id": "79e05663-7f03-45d2-a092-8b94062f22ab", | ||||
| 			        "protocol": "TCP", | ||||
| 			        "name": "db", | ||||
| 			        "admin_state_up": true, | ||||
| 			        "default_tls_container_ref": "2c433435-20de-4411-84ae-9cc8917def76", | ||||
| 			        "default_pool_id": "41efe233-7591-43c5-9cf7-923964759f9e", | ||||
| 			        "protocol_port": 3306 | ||||
| 			    } | ||||
| 		}`) | ||||
|  | ||||
| 		w.WriteHeader(http.StatusAccepted) | ||||
| 		w.Header().Add("Content-Type", "application/json") | ||||
| 		fmt.Fprintf(w, response) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleListenerGetSuccessfully sets up the test server to respond to a listener Get request. | ||||
| func HandleListenerGetSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
|  | ||||
| 		fmt.Fprintf(w, SingleListenerBody) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleListenerDeletionSuccessfully sets up the test server to respond to a listener deletion request. | ||||
| func HandleListenerDeletionSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "DELETE") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
|  | ||||
| 		w.WriteHeader(http.StatusNoContent) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleListenerUpdateSuccessfully sets up the test server to respond to a listener Update request. | ||||
| func HandleListenerUpdateSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/listeners/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "PUT") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
| 		th.TestHeader(t, r, "Content-Type", "application/json") | ||||
| 		th.TestJSONRequest(t, r, `{ | ||||
| 			"listener": { | ||||
| 				"name": "NewListenerName", | ||||
| 				"connection_limit": 1001 | ||||
| 			} | ||||
| 		}`) | ||||
|  | ||||
| 		fmt.Fprintf(w, PostUpdateListenerBody) | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										279
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/requests.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/requests.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,279 @@ | ||||
| package listeners | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/rackspace/gophercloud" | ||||
| 	"github.com/rackspace/gophercloud/pagination" | ||||
| ) | ||||
|  | ||||
| // AdminState gives users a solid type to work with for create and update | ||||
| // operations. It is recommended that users use the `Up` and `Down` enums. | ||||
| type AdminState *bool | ||||
|  | ||||
| type listenerOpts struct { | ||||
| 	// Required. The protocol - can either be TCP, HTTP or HTTPS. | ||||
| 	Protocol Protocol | ||||
|  | ||||
| 	// Required. The port on which to listen for client traffic. | ||||
| 	ProtocolPort int | ||||
|  | ||||
| 	// Required for admins. Indicates the owner of the Listener. | ||||
| 	TenantID string | ||||
|  | ||||
| 	// Required. The load balancer on which to provision this listener. | ||||
| 	LoadbalancerID string | ||||
|  | ||||
| 	// Human-readable name for the Listener. Does not have to be unique. | ||||
| 	Name string | ||||
|  | ||||
| 	// Optional. The ID of the default pool with which the Listener is associated. | ||||
| 	DefaultPoolID string | ||||
|  | ||||
| 	// Optional. Human-readable description for the Listener. | ||||
| 	Description string | ||||
|  | ||||
| 	// Optional. The maximum number of connections allowed for the Listener. | ||||
| 	ConnLimit *int | ||||
|  | ||||
| 	// Optional. A reference to a container of TLS secrets. | ||||
| 	DefaultTlsContainerRef string | ||||
|  | ||||
| 	// Optional. A list of references to TLS secrets. | ||||
| 	SniContainerRefs []string | ||||
|  | ||||
| 	// Optional. The administrative state of the Listener. A valid value is true (UP) | ||||
| 	// or false (DOWN). | ||||
| 	AdminStateUp *bool | ||||
| } | ||||
|  | ||||
| // Convenience vars for AdminStateUp values. | ||||
| var ( | ||||
| 	iTrue  = true | ||||
| 	iFalse = false | ||||
|  | ||||
| 	Up   AdminState = &iTrue | ||||
| 	Down AdminState = &iFalse | ||||
| ) | ||||
|  | ||||
| // ListOptsBuilder allows extensions to add additional parameters to the | ||||
| // List request. | ||||
| type ListOptsBuilder interface { | ||||
| 	ToListenerListQuery() (string, error) | ||||
| } | ||||
|  | ||||
| // 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 | ||||
| // sort by a particular listener attribute. SortDir sets the direction, and is | ||||
| // either `asc' or `desc'. Marker and Limit are used for pagination. | ||||
| type ListOpts struct { | ||||
| 	ID              string `q:"id"` | ||||
| 	Name            string `q:"name"` | ||||
| 	AdminStateUp    *bool  `q:"admin_state_up"` | ||||
| 	TenantID        string `q:"tenant_id"` | ||||
| 	LoadbalancerID  string `q:"loadbalancer_id"` | ||||
| 	DefaultPoolID   string `q:"default_pool_id"` | ||||
| 	Protocol        string `q:"protocol"` | ||||
| 	ProtocolPort    int    `q:"protocol_port"` | ||||
| 	ConnectionLimit int    `q:"connection_limit"` | ||||
| 	Limit           int    `q:"limit"` | ||||
| 	Marker          string `q:"marker"` | ||||
| 	SortKey         string `q:"sort_key"` | ||||
| 	SortDir         string `q:"sort_dir"` | ||||
| } | ||||
|  | ||||
| // ToListenerListQuery formats a ListOpts into a query string. | ||||
| func (opts ListOpts) ToListenerListQuery() (string, error) { | ||||
| 	q, err := gophercloud.BuildQueryString(opts) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return q.String(), nil | ||||
| } | ||||
|  | ||||
| // 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. | ||||
| // | ||||
| // Default policy settings return only those routers 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 { | ||||
| 		query, err := opts.ToListenerListQuery() | ||||
| 		if err != nil { | ||||
| 			return pagination.Pager{Err: err} | ||||
| 		} | ||||
| 		url += query | ||||
| 	} | ||||
|  | ||||
| 	return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { | ||||
| 		return ListenerPage{pagination.LinkedPageBase{PageResult: r}} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| type Protocol string | ||||
|  | ||||
| // Supported attributes for create/update operations. | ||||
| const ( | ||||
| 	ProtocolTCP   Protocol = "TCP" | ||||
| 	ProtocolHTTP  Protocol = "HTTP" | ||||
| 	ProtocolHTTPS Protocol = "HTTPS" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	errLoadbalancerIdRequired = fmt.Errorf("LoadbalancerID is required") | ||||
| 	errProtocolRequired       = fmt.Errorf("Protocol is required") | ||||
| 	errProtocolPortRequired   = fmt.Errorf("ProtocolPort  is required") | ||||
| ) | ||||
|  | ||||
| // 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. | ||||
| type CreateOptsBuilder interface { | ||||
| 	ToListenerCreateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // CreateOpts is the common options struct used in this package's Create | ||||
| // operation. | ||||
| type CreateOpts listenerOpts | ||||
|  | ||||
| // ToListenerCreateMap casts a CreateOpts struct to a map. | ||||
| func (opts CreateOpts) ToListenerCreateMap() (map[string]interface{}, error) { | ||||
| 	l := make(map[string]interface{}) | ||||
|  | ||||
| 	if opts.LoadbalancerID != "" { | ||||
| 		l["loadbalancer_id"] = opts.LoadbalancerID | ||||
| 	} else { | ||||
| 		return nil, errLoadbalancerIdRequired | ||||
| 	} | ||||
| 	if opts.Protocol != "" { | ||||
| 		l["protocol"] = opts.Protocol | ||||
| 	} else { | ||||
| 		return nil, errProtocolRequired | ||||
| 	} | ||||
| 	if opts.ProtocolPort != 0 { | ||||
| 		l["protocol_port"] = opts.ProtocolPort | ||||
| 	} else { | ||||
| 		return nil, errProtocolPortRequired | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		l["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
| 	if opts.Name != "" { | ||||
| 		l["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.TenantID != "" { | ||||
| 		l["tenant_id"] = opts.TenantID | ||||
| 	} | ||||
| 	if opts.DefaultPoolID != "" { | ||||
| 		l["default_pool_id"] = opts.DefaultPoolID | ||||
| 	} | ||||
| 	if opts.Description != "" { | ||||
| 		l["description"] = opts.Description | ||||
| 	} | ||||
| 	if opts.ConnLimit != nil { | ||||
| 		l["connection_limit"] = &opts.ConnLimit | ||||
| 	} | ||||
| 	if opts.DefaultTlsContainerRef != "" { | ||||
| 		l["default_tls_container_ref"] = opts.DefaultTlsContainerRef | ||||
| 	} | ||||
| 	if opts.SniContainerRefs != nil { | ||||
| 		l["sni_container_refs"] = opts.SniContainerRefs | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"listener": l}, nil | ||||
| } | ||||
|  | ||||
| // Create is an operation which provisions a new Listeners based on the | ||||
| // 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 Listeners on behalf of other tenants by | ||||
| // specifying a TenantID attribute different than their own. | ||||
| func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { | ||||
| 	var res CreateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToListenerCreateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	// Send request to API | ||||
| 	_, res.Err = c.Post(rootURL(c), reqBody, &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // Get retrieves a particular Listeners based on its unique ID. | ||||
| func Get(c *gophercloud.ServiceClient, id string) GetResult { | ||||
| 	var res GetResult | ||||
| 	_, res.Err = c.Get(resourceURL(c, id), &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // 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. | ||||
| type UpdateOptsBuilder interface { | ||||
| 	ToListenerUpdateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // UpdateOpts is the common options struct used in this package's Update | ||||
| // operation. | ||||
| type UpdateOpts listenerOpts | ||||
|  | ||||
| // ToListenerUpdateMap casts a UpdateOpts struct to a map. | ||||
| func (opts UpdateOpts) ToListenerUpdateMap() (map[string]interface{}, error) { | ||||
| 	l := make(map[string]interface{}) | ||||
|  | ||||
| 	if opts.Name != "" { | ||||
| 		l["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.Description != "" { | ||||
| 		l["description"] = opts.Description | ||||
| 	} | ||||
| 	if opts.ConnLimit != nil { | ||||
| 		l["connection_limit"] = &opts.ConnLimit | ||||
| 	} | ||||
| 	if opts.DefaultTlsContainerRef != "" { | ||||
| 		l["default_tls_container_ref"] = opts.DefaultTlsContainerRef | ||||
| 	} | ||||
| 	if opts.SniContainerRefs != nil { | ||||
| 		l["sni_container_refs"] = opts.SniContainerRefs | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		l["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"listener": l}, nil | ||||
| } | ||||
|  | ||||
| // Update is an operation which modifies the attributes of the specified Listener. | ||||
| func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult { | ||||
| 	var res UpdateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToListenerUpdateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	// Send request to API | ||||
| 	_, res.Err = c.Put(resourceURL(c, id), reqBody, &res.Body, &gophercloud.RequestOpts{ | ||||
| 		OkCodes: []int{200, 202}, | ||||
| 	}) | ||||
|  | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // Delete will permanently delete a particular Listeners based on its unique ID. | ||||
| func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { | ||||
| 	var res DeleteResult | ||||
| 	_, res.Err = c.Delete(resourceURL(c, id), nil) | ||||
| 	return res | ||||
| } | ||||
							
								
								
									
										139
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/results.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/results.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | ||||
| package listeners | ||||
|  | ||||
| import ( | ||||
| 	"github.com/mitchellh/mapstructure" | ||||
| 	"github.com/rackspace/gophercloud" | ||||
| 	"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools" | ||||
| 	"github.com/rackspace/gophercloud/pagination" | ||||
| ) | ||||
|  | ||||
| type LoadBalancerID struct { | ||||
| 	ID string `mapstructure:"id" json:"id"` | ||||
| } | ||||
|  | ||||
| // Listener is the primary load balancing configuration object that specifies | ||||
| // the loadbalancer and port on which client traffic is received, as well | ||||
| // as other details such as the load balancing method to be use, protocol, etc. | ||||
| type Listener struct { | ||||
| 	// The unique ID for the Listener. | ||||
| 	ID string `mapstructure:"id" json:"id"` | ||||
|  | ||||
| 	// Owner of the Listener. Only an admin user can specify a tenant ID other than its own. | ||||
| 	TenantID string `mapstructure:"tenant_id" json:"tenant_id"` | ||||
|  | ||||
| 	// Human-readable name for the Listener. Does not have to be unique. | ||||
| 	Name string `mapstructure:"name" json:"name"` | ||||
|  | ||||
| 	// Human-readable description for the Listener. | ||||
| 	Description string `mapstructure:"description" json:"description"` | ||||
|  | ||||
| 	// The protocol to loadbalance. A valid value is TCP, HTTP, or HTTPS. | ||||
| 	Protocol string `mapstructure:"protocol" 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 `mapstructure:"protocol_port" json:"protocol_port"` | ||||
|  | ||||
| 	// The UUID of default pool. Must have compatible protocol with listener. | ||||
| 	DefaultPoolID string `mapstructure:"default_pool_id" json:"default_pool_id"` | ||||
|  | ||||
| 	// A list of load balancer IDs. | ||||
| 	Loadbalancers []LoadBalancerID `mapstructure:"loadbalancers" json:"loadbalancers"` | ||||
|  | ||||
| 	// The maximum number of connections allowed for the Loadbalancer. Default is -1, | ||||
| 	// meaning no limit. | ||||
| 	ConnLimit int `mapstructure:"connection_limit" json:"connection_limit"` | ||||
|  | ||||
| 	// The list of references to TLS secrets. | ||||
| 	SniContainerRefs []string `mapstructure:"sni_container_refs" json:"sni_container_refs"` | ||||
|  | ||||
| 	// Optional. A reference to a container of TLS secrets. | ||||
| 	DefaultTlsContainerRef string `mapstructure:"default_tls_container_ref" json:"default_tls_container_ref"` | ||||
|  | ||||
| 	// The administrative state of the Listener. A valid value is true (UP) or false (DOWN). | ||||
| 	AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"` | ||||
|  | ||||
| 	Pools []pools.Pool `mapstructure:"pools" json:"pools"` | ||||
| } | ||||
|  | ||||
| // ListenerPage is the page returned by a pager when traversing over a | ||||
| // collection of routers. | ||||
| type ListenerPage 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. | ||||
| func (p ListenerPage) NextPageURL() (string, error) { | ||||
| 	type resp struct { | ||||
| 		Links []gophercloud.Link `mapstructure:"listeners_links"` | ||||
| 	} | ||||
|  | ||||
| 	var r resp | ||||
| 	err := mapstructure.Decode(p.Body, &r) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return gophercloud.ExtractNextURL(r.Links) | ||||
| } | ||||
|  | ||||
| // IsEmpty checks whether a RouterPage struct is empty. | ||||
| func (p ListenerPage) IsEmpty() (bool, error) { | ||||
| 	is, err := ExtractListeners(p) | ||||
| 	if err != nil { | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return len(is) == 0, nil | ||||
| } | ||||
|  | ||||
| // ExtractListeners accepts a Page struct, specifically a ListenerPage struct, | ||||
| // and extracts the elements into a slice of Listener structs. In other words, | ||||
| // a generic collection is mapped into a relevant slice. | ||||
| func ExtractListeners(page pagination.Page) ([]Listener, error) { | ||||
| 	var resp struct { | ||||
| 		Listeners []Listener `mapstructure:"listeners" json:"listeners"` | ||||
| 	} | ||||
| 	err := mapstructure.Decode(page.(ListenerPage).Body, &resp) | ||||
| 	return resp.Listeners, err | ||||
| } | ||||
|  | ||||
| type commonResult struct { | ||||
| 	gophercloud.Result | ||||
| } | ||||
|  | ||||
| // Extract is a function that accepts a result and extracts a router. | ||||
| func (r commonResult) Extract() (*Listener, error) { | ||||
| 	if r.Err != nil { | ||||
| 		return nil, r.Err | ||||
| 	} | ||||
|  | ||||
| 	var res struct { | ||||
| 		Listener *Listener `mapstructure:"listener" json:"listener"` | ||||
| 	} | ||||
|  | ||||
| 	err := mapstructure.Decode(r.Body, &res) | ||||
|  | ||||
| 	return res.Listener, err | ||||
| } | ||||
|  | ||||
| // CreateResult represents the result of a create operation. | ||||
| type CreateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // GetResult represents the result of a get operation. | ||||
| type GetResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // UpdateResult represents the result of an update operation. | ||||
| type UpdateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // DeleteResult represents the result of a delete operation. | ||||
| type DeleteResult struct { | ||||
| 	gophercloud.ErrResult | ||||
| } | ||||
							
								
								
									
										16
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/urls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners/urls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| package listeners | ||||
|  | ||||
| import "github.com/rackspace/gophercloud" | ||||
|  | ||||
| const ( | ||||
| 	rootPath     = "lbaas" | ||||
| 	resourcePath = "listeners" | ||||
| ) | ||||
|  | ||||
| func rootURL(c *gophercloud.ServiceClient) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath) | ||||
| } | ||||
|  | ||||
| func resourceURL(c *gophercloud.ServiceClient, id string) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath, id) | ||||
| } | ||||
							
								
								
									
										278
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/fixtures.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/fixtures.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,278 @@ | ||||
| // +build fixtures | ||||
|  | ||||
| package loadbalancers | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"testing" | ||||
|  | ||||
| 	th "github.com/rackspace/gophercloud/testhelper" | ||||
| 	"github.com/rackspace/gophercloud/testhelper/client" | ||||
|  | ||||
| 	"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners" | ||||
| 	"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors" | ||||
| 	"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools" | ||||
| ) | ||||
|  | ||||
| // LoadbalancersListBody contains the canned body of a loadbalancer list response. | ||||
| const LoadbalancersListBody = ` | ||||
| { | ||||
| 	"loadbalancers":[ | ||||
| 	         { | ||||
| 			"id": "c331058c-6a40-4144-948e-b9fb1df9db4b", | ||||
| 			"tenant_id": "54030507-44f7-473c-9342-b4d14a95f692", | ||||
| 			"name": "web_lb", | ||||
| 			"description": "lb config for the web tier", | ||||
| 			"vip_subnet_id": "8a49c438-848f-467b-9655-ea1548708154", | ||||
| 			"vip_address": "10.30.176.47", | ||||
| 			"flavor": "small", | ||||
| 			"provider": "haproxy", | ||||
| 			"admin_state_up": true, | ||||
| 			"provisioning_status": "ACTIVE", | ||||
| 			"operating_status": "ONLINE" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"id": "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 			"tenant_id": "54030507-44f7-473c-9342-b4d14a95f692", | ||||
| 			"name": "db_lb", | ||||
| 			"description": "lb config for the db tier", | ||||
| 			"vip_subnet_id": "9cedb85d-0759-4898-8a4b-fa5a5ea10086", | ||||
| 			"vip_address": "10.30.176.48", | ||||
| 			"flavor": "medium", | ||||
| 			"provider": "haproxy", | ||||
| 			"admin_state_up": true, | ||||
| 			"provisioning_status": "PENDING_CREATE", | ||||
| 			"operating_status": "OFFLINE" | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
| ` | ||||
|  | ||||
| // SingleLoadbalancerBody is the canned body of a Get request on an existing loadbalancer. | ||||
| const SingleLoadbalancerBody = ` | ||||
| { | ||||
| 	"loadbalancer": { | ||||
| 		"id": "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 		"tenant_id": "54030507-44f7-473c-9342-b4d14a95f692", | ||||
| 		"name": "db_lb", | ||||
| 		"description": "lb config for the db tier", | ||||
| 		"vip_subnet_id": "9cedb85d-0759-4898-8a4b-fa5a5ea10086", | ||||
| 		"vip_address": "10.30.176.48", | ||||
| 		"flavor": "medium", | ||||
| 		"provider": "haproxy", | ||||
| 		"admin_state_up": true, | ||||
| 		"provisioning_status": "PENDING_CREATE", | ||||
| 		"operating_status": "OFFLINE" | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| // PostUpdateLoadbalancerBody is the canned response body of a Update request on an existing loadbalancer. | ||||
| const PostUpdateLoadbalancerBody = ` | ||||
| { | ||||
| 	"loadbalancer": { | ||||
| 		"id": "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 		"tenant_id": "54030507-44f7-473c-9342-b4d14a95f692", | ||||
| 		"name": "NewLoadbalancerName", | ||||
| 		"description": "lb config for the db tier", | ||||
| 		"vip_subnet_id": "9cedb85d-0759-4898-8a4b-fa5a5ea10086", | ||||
| 		"vip_address": "10.30.176.48", | ||||
| 		"flavor": "medium", | ||||
| 		"provider": "haproxy", | ||||
| 		"admin_state_up": true, | ||||
| 		"provisioning_status": "PENDING_CREATE", | ||||
| 		"operating_status": "OFFLINE" | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| // SingleLoadbalancerBody is the canned body of a Get request on an existing loadbalancer. | ||||
| const LoadbalancerStatuesesTree = ` | ||||
| { | ||||
| 	"statuses" : { | ||||
| 		"loadbalancer": { | ||||
| 			"id": "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 			"name": "db_lb", | ||||
| 			"provisioning_status": "PENDING_UPDATE", | ||||
| 			"operating_status": "ACTIVE", | ||||
| 			"listeners": [{ | ||||
| 				"id": "db902c0c-d5ff-4753-b465-668ad9656918", | ||||
| 				"name": "db", | ||||
| 				"pools": [{ | ||||
| 					"id": "fad389a3-9a4a-4762-a365-8c7038508b5d", | ||||
| 					"name": "db", | ||||
| 					"healthmonitor": { | ||||
| 						"id": "67306cda-815d-4354-9fe4-59e09da9c3c5", | ||||
| 						"type":"PING" | ||||
| 					}, | ||||
| 					"members":[{ | ||||
| 						"id": "2a280670-c202-4b0b-a562-34077415aabf", | ||||
| 						"name": "db", | ||||
| 						"address": "10.0.2.11", | ||||
| 						"protocol_port": 80 | ||||
| 					}] | ||||
| 				}] | ||||
| 			}] | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| var ( | ||||
| 	LoadbalancerWeb = LoadBalancer{ | ||||
| 		ID:                 "c331058c-6a40-4144-948e-b9fb1df9db4b", | ||||
| 		TenantID:           "54030507-44f7-473c-9342-b4d14a95f692", | ||||
| 		Name:               "web_lb", | ||||
| 		Description:        "lb config for the web tier", | ||||
| 		VipSubnetID:        "8a49c438-848f-467b-9655-ea1548708154", | ||||
| 		VipAddress:         "10.30.176.47", | ||||
| 		Flavor:             "small", | ||||
| 		Provider:           "haproxy", | ||||
| 		AdminStateUp:       true, | ||||
| 		ProvisioningStatus: "ACTIVE", | ||||
| 		OperatingStatus:    "ONLINE", | ||||
| 	} | ||||
| 	LoadbalancerDb = LoadBalancer{ | ||||
| 		ID:                 "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 		TenantID:           "54030507-44f7-473c-9342-b4d14a95f692", | ||||
| 		Name:               "db_lb", | ||||
| 		Description:        "lb config for the db tier", | ||||
| 		VipSubnetID:        "9cedb85d-0759-4898-8a4b-fa5a5ea10086", | ||||
| 		VipAddress:         "10.30.176.48", | ||||
| 		Flavor:             "medium", | ||||
| 		Provider:           "haproxy", | ||||
| 		AdminStateUp:       true, | ||||
| 		ProvisioningStatus: "PENDING_CREATE", | ||||
| 		OperatingStatus:    "OFFLINE", | ||||
| 	} | ||||
| 	LoadbalancerUpdated = LoadBalancer{ | ||||
| 		ID:                 "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 		TenantID:           "54030507-44f7-473c-9342-b4d14a95f692", | ||||
| 		Name:               "NewLoadbalancerName", | ||||
| 		Description:        "lb config for the db tier", | ||||
| 		VipSubnetID:        "9cedb85d-0759-4898-8a4b-fa5a5ea10086", | ||||
| 		VipAddress:         "10.30.176.48", | ||||
| 		Flavor:             "medium", | ||||
| 		Provider:           "haproxy", | ||||
| 		AdminStateUp:       true, | ||||
| 		ProvisioningStatus: "PENDING_CREATE", | ||||
| 		OperatingStatus:    "OFFLINE", | ||||
| 	} | ||||
| 	LoadbalancerStatusesTree = LoadBalancer{ | ||||
| 		ID:                 "36e08a3e-a78f-4b40-a229-1e7e23eee1ab", | ||||
| 		Name:               "db_lb", | ||||
| 		ProvisioningStatus: "PENDING_UPDATE", | ||||
| 		OperatingStatus:    "ACTIVE", | ||||
| 		Listeners: []listeners.Listener{{ | ||||
| 			ID:   "db902c0c-d5ff-4753-b465-668ad9656918", | ||||
| 			Name: "db", | ||||
| 			Pools: []pools.Pool{{ | ||||
| 				ID:   "fad389a3-9a4a-4762-a365-8c7038508b5d", | ||||
| 				Name: "db", | ||||
| 				Monitor: monitors.Monitor{ | ||||
| 					ID:   "67306cda-815d-4354-9fe4-59e09da9c3c5", | ||||
| 					Type: "PING", | ||||
| 				}, | ||||
| 				Members: []pools.Member{{ | ||||
| 					ID:           "2a280670-c202-4b0b-a562-34077415aabf", | ||||
| 					Name:         "db", | ||||
| 					Address:      "10.0.2.11", | ||||
| 					ProtocolPort: 80, | ||||
| 				}}, | ||||
| 			}}, | ||||
| 		}}, | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // HandleLoadbalancerListSuccessfully sets up the test server to respond to a loadbalancer List request. | ||||
| func HandleLoadbalancerListSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
|  | ||||
| 		w.Header().Add("Content-Type", "application/json") | ||||
| 		r.ParseForm() | ||||
| 		marker := r.Form.Get("marker") | ||||
| 		switch marker { | ||||
| 		case "": | ||||
| 			fmt.Fprintf(w, LoadbalancersListBody) | ||||
| 		case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab": | ||||
| 			fmt.Fprintf(w, `{ "loadbalancers": [] }`) | ||||
| 		default: | ||||
| 			t.Fatalf("/v2.0/lbaas/loadbalancers invoked with unexpected marker=[%s]", marker) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleLoadbalancerCreationSuccessfully sets up the test server to respond to a loadbalancer creation request | ||||
| // with a given response. | ||||
| func HandleLoadbalancerCreationSuccessfully(t *testing.T, response string) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "POST") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestJSONRequest(t, r, `{ | ||||
| 			"loadbalancer": { | ||||
| 				"name": "db_lb", | ||||
| 				"vip_subnet_id": "9cedb85d-0759-4898-8a4b-fa5a5ea10086", | ||||
| 				"vip_address": "10.30.176.48", | ||||
| 				"flavor": "medium", | ||||
| 				"provider": "haproxy", | ||||
| 				"admin_state_up": true | ||||
| 			} | ||||
| 		}`) | ||||
|  | ||||
| 		w.WriteHeader(http.StatusAccepted) | ||||
| 		w.Header().Add("Content-Type", "application/json") | ||||
| 		fmt.Fprintf(w, response) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleLoadbalancerGetSuccessfully sets up the test server to respond to a loadbalancer Get request. | ||||
| func HandleLoadbalancerGetSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
|  | ||||
| 		fmt.Fprintf(w, SingleLoadbalancerBody) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleLoadbalancerGetStatusesTree sets up the test server to respond to a loadbalancer Get statuses tree request. | ||||
| func HandleLoadbalancerGetStatusesTree(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab/statuses", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
|  | ||||
| 		fmt.Fprintf(w, LoadbalancerStatuesesTree) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleLoadbalancerDeletionSuccessfully sets up the test server to respond to a loadbalancer deletion request. | ||||
| func HandleLoadbalancerDeletionSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "DELETE") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
|  | ||||
| 		w.WriteHeader(http.StatusNoContent) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleLoadbalancerUpdateSuccessfully sets up the test server to respond to a loadbalancer Update request. | ||||
| func HandleLoadbalancerUpdateSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/loadbalancers/36e08a3e-a78f-4b40-a229-1e7e23eee1ab", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "PUT") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
| 		th.TestHeader(t, r, "Content-Type", "application/json") | ||||
| 		th.TestJSONRequest(t, r, `{ | ||||
| 			"loadbalancer": { | ||||
| 				"name": "NewLoadbalancerName" | ||||
| 			} | ||||
| 		}`) | ||||
|  | ||||
| 		fmt.Fprintf(w, PostUpdateLoadbalancerBody) | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										248
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/requests.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/requests.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,248 @@ | ||||
| package loadbalancers | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/rackspace/gophercloud" | ||||
| 	"github.com/rackspace/gophercloud/pagination" | ||||
| ) | ||||
|  | ||||
| // AdminState gives users a solid type to work with for create and update | ||||
| // operations. It is recommended that users use the `Up` and `Down` enums. | ||||
| type AdminState *bool | ||||
|  | ||||
| type loadbalancerOpts struct { | ||||
| 	// Optional. Human-readable name for the Loadbalancer. Does not have to be unique. | ||||
| 	Name string | ||||
|  | ||||
| 	// Optional. Human-readable description for the Loadbalancer. | ||||
| 	Description string | ||||
|  | ||||
| 	// 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). | ||||
| 	VipSubnetID string | ||||
|  | ||||
| 	// Required for admins. The UUID of the tenant who owns the Loadbalancer. | ||||
| 	// Only administrative users can specify a tenant UUID other than their own. | ||||
| 	TenantID string | ||||
|  | ||||
| 	// Optional. The IP address of the Loadbalancer. | ||||
| 	VipAddress string | ||||
|  | ||||
| 	// Optional. The administrative state of the Loadbalancer. A valid value is true (UP) | ||||
| 	// or false (DOWN). | ||||
| 	AdminStateUp *bool | ||||
|  | ||||
| 	// Optional. The UUID of a flavor. | ||||
| 	Flavor string | ||||
|  | ||||
| 	// Optional. The name of the provider. | ||||
| 	Provider string | ||||
| } | ||||
|  | ||||
| // Convenience vars for AdminStateUp values. | ||||
| var ( | ||||
| 	iTrue  = true | ||||
| 	iFalse = false | ||||
|  | ||||
| 	Up   AdminState = &iTrue | ||||
| 	Down AdminState = &iFalse | ||||
| ) | ||||
|  | ||||
| // ListOptsBuilder allows extensions to add additional parameters to the | ||||
| // List request. | ||||
| type ListOptsBuilder interface { | ||||
| 	ToLoadbalancerListQuery() (string, error) | ||||
| } | ||||
|  | ||||
| // 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 Loadbalancer attributes you want to see returned. SortKey allows you to | ||||
| // sort by a particular attribute. SortDir sets the direction, and is | ||||
| // either `asc' or `desc'. Marker and Limit are used for pagination. | ||||
| type ListOpts struct { | ||||
| 	Description        string `q:"description"` | ||||
| 	AdminStateUp       *bool  `q:"admin_state_up"` | ||||
| 	TenantID           string `q:"tenant_id"` | ||||
| 	ProvisioningStatus string `q:"provisioning_status"` | ||||
| 	VipAddress         string `q:"vip_address"` | ||||
| 	VipSubnetID        string `q:"vip_subnet_id"` | ||||
| 	ID                 string `q:"id"` | ||||
| 	OperatingStatus    string `q:"operating_status"` | ||||
| 	Name               string `q:"name"` | ||||
| 	Flavor             string `q:"flavor"` | ||||
| 	Provider           string `q:"provider"` | ||||
| 	Limit              int    `q:"limit"` | ||||
| 	Marker             string `q:"marker"` | ||||
| 	SortKey            string `q:"sort_key"` | ||||
| 	SortDir            string `q:"sort_dir"` | ||||
| } | ||||
|  | ||||
| // ToLoadbalancerListQuery formats a ListOpts into a query string. | ||||
| func (opts ListOpts) ToLoadbalancerListQuery() (string, error) { | ||||
| 	q, err := gophercloud.BuildQueryString(opts) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return q.String(), nil | ||||
| } | ||||
|  | ||||
| // 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. | ||||
| // | ||||
| // Default policy settings return only those routers 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 { | ||||
| 		query, err := opts.ToLoadbalancerListQuery() | ||||
| 		if err != nil { | ||||
| 			return pagination.Pager{Err: err} | ||||
| 		} | ||||
| 		url += query | ||||
| 	} | ||||
|  | ||||
| 	return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { | ||||
| 		return LoadbalancerPage{pagination.LinkedPageBase{PageResult: r}} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	errVipSubnetIDRequried = fmt.Errorf("VipSubnetID is required") | ||||
| ) | ||||
|  | ||||
| // 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. | ||||
| type CreateOptsBuilder interface { | ||||
| 	ToLoadbalancerCreateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // CreateOpts is the common options struct used in this package's Create | ||||
| // operation. | ||||
| type CreateOpts loadbalancerOpts | ||||
|  | ||||
| // ToLoadbalancerCreateMap casts a CreateOpts struct to a map. | ||||
| func (opts CreateOpts) ToLoadbalancerCreateMap() (map[string]interface{}, error) { | ||||
| 	l := make(map[string]interface{}) | ||||
|  | ||||
| 	if opts.VipSubnetID != "" { | ||||
| 		l["vip_subnet_id"] = opts.VipSubnetID | ||||
| 	} else { | ||||
| 		return nil, errVipSubnetIDRequried | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		l["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
| 	if opts.Name != "" { | ||||
| 		l["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.TenantID != "" { | ||||
| 		l["tenant_id"] = opts.TenantID | ||||
| 	} | ||||
| 	if opts.Description != "" { | ||||
| 		l["description"] = opts.Description | ||||
| 	} | ||||
| 	if opts.VipAddress != "" { | ||||
| 		l["vip_address"] = opts.VipAddress | ||||
| 	} | ||||
| 	if opts.Flavor != "" { | ||||
| 		l["flavor"] = opts.Flavor | ||||
| 	} | ||||
| 	if opts.Provider != "" { | ||||
| 		l["provider"] = opts.Provider | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"loadbalancer": l}, nil | ||||
| } | ||||
|  | ||||
| // Create is an operation which provisions a new loadbalancer based on the | ||||
| // 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 CreateOpts) CreateResult { | ||||
| 	var res CreateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToLoadbalancerCreateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	// Send request to API | ||||
| 	_, res.Err = c.Post(rootURL(c), reqBody, &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // Get retrieves a particular Loadbalancer based on its unique ID. | ||||
| func Get(c *gophercloud.ServiceClient, id string) GetResult { | ||||
| 	var res GetResult | ||||
| 	_, res.Err = c.Get(resourceURL(c, id), &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // 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. | ||||
| type UpdateOptsBuilder interface { | ||||
| 	ToLoadbalancerUpdateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // UpdateOpts is the common options struct used in this package's Update | ||||
| // operation. | ||||
| type UpdateOpts loadbalancerOpts | ||||
|  | ||||
| // ToLoadbalancerUpdateMap casts a UpdateOpts struct to a map. | ||||
| func (opts UpdateOpts) ToLoadbalancerUpdateMap() (map[string]interface{}, error) { | ||||
| 	l := make(map[string]interface{}) | ||||
|  | ||||
| 	if opts.Name != "" { | ||||
| 		l["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.Description != "" { | ||||
| 		l["description"] = opts.Description | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		l["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"loadbalancer": l}, nil | ||||
| } | ||||
|  | ||||
| // Update is an operation which modifies the attributes of the specified Loadbalancer. | ||||
| func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult { | ||||
| 	var res UpdateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToLoadbalancerUpdateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	// Send request to API | ||||
| 	_, res.Err = c.Put(resourceURL(c, id), reqBody, &res.Body, &gophercloud.RequestOpts{ | ||||
| 		OkCodes: []int{200, 202}, | ||||
| 	}) | ||||
|  | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // Delete will permanently delete a particular Loadbalancer based on its unique ID. | ||||
| func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { | ||||
| 	var res DeleteResult | ||||
| 	_, res.Err = c.Delete(resourceURL(c, id), nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| func GetStatuses(c *gophercloud.ServiceClient, id string) GetResult { | ||||
| 	var res GetResult | ||||
| 	_, res.Err = c.Get(statusRootURL(c, id), &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
							
								
								
									
										146
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/results.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/results.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | ||||
| package loadbalancers | ||||
|  | ||||
| import ( | ||||
| 	"github.com/mitchellh/mapstructure" | ||||
| 	"github.com/rackspace/gophercloud" | ||||
| 	"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/listeners" | ||||
| 	"github.com/rackspace/gophercloud/pagination" | ||||
| ) | ||||
|  | ||||
| // 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 `mapstructure:"description" json:"description"` | ||||
|  | ||||
| 	// The administrative state of the Loadbalancer. A valid value is true (UP) or false (DOWN). | ||||
| 	AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"` | ||||
|  | ||||
| 	// Owner of the LoadBalancer. Only an admin user can specify a tenant ID other than its own. | ||||
| 	TenantID string `mapstructure:"tenant_id" json:"tenant_id"` | ||||
|  | ||||
| 	// The provisioning status of the LoadBalancer. This value is ACTIVE, PENDING_CREATE or ERROR. | ||||
| 	ProvisioningStatus string `mapstructure:"provisioning_status" json:"provisioning_status"` | ||||
|  | ||||
| 	// The IP address of the Loadbalancer. | ||||
| 	VipAddress string `mapstructure:"vip_address" json:"vip_address"` | ||||
|  | ||||
| 	// The UUID of the subnet on which to allocate the virtual IP for the Loadbalancer address. | ||||
| 	VipSubnetID string `mapstructure:"vip_subnet_id" json:"vip_subnet_id"` | ||||
|  | ||||
| 	// The unique ID for the LoadBalancer. | ||||
| 	ID string `mapstructure:"id" json:"id"` | ||||
|  | ||||
| 	// The operating status of the LoadBalancer. This value is ONLINE or OFFLINE. | ||||
| 	OperatingStatus string `mapstructure:"operating_status" json:"operating_status"` | ||||
|  | ||||
| 	// Human-readable name for the LoadBalancer. Does not have to be unique. | ||||
| 	Name string `mapstructure:"name" json:"name"` | ||||
|  | ||||
| 	// The UUID of a flavor if set. | ||||
| 	Flavor string `mapstructure:"flavor" json:"flavor"` | ||||
|  | ||||
| 	// The name of the provider. | ||||
| 	Provider string `mapstructure:"provider" json:"provider"` | ||||
|  | ||||
| 	Listeners []listeners.Listener `mapstructure:"listeners" json:"listeners"` | ||||
| } | ||||
|  | ||||
| type StatusTree struct { | ||||
| 	Loadbalancer *LoadBalancer `mapstructure:"loadbalancer" json:"loadbalancer"` | ||||
| } | ||||
|  | ||||
| // LoadbalancerPage is the page returned by a pager when traversing over a | ||||
| // collection of routers. | ||||
| 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. | ||||
| func (p LoadbalancerPage) NextPageURL() (string, error) { | ||||
| 	type resp struct { | ||||
| 		Links []gophercloud.Link `mapstructure:"loadbalancers_links"` | ||||
| 	} | ||||
|  | ||||
| 	var r resp | ||||
| 	err := mapstructure.Decode(p.Body, &r) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return gophercloud.ExtractNextURL(r.Links) | ||||
| } | ||||
|  | ||||
| // IsEmpty checks whether a RouterPage struct is empty. | ||||
| func (p LoadbalancerPage) IsEmpty() (bool, error) { | ||||
| 	is, err := ExtractLoadbalancers(p) | ||||
| 	if err != nil { | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return len(is) == 0, nil | ||||
| } | ||||
|  | ||||
| // 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(page pagination.Page) ([]LoadBalancer, error) { | ||||
| 	var resp struct { | ||||
| 		LoadBalancers []LoadBalancer `mapstructure:"loadbalancers" json:"loadbalancers"` | ||||
| 	} | ||||
| 	err := mapstructure.Decode(page.(LoadbalancerPage).Body, &resp) | ||||
|  | ||||
| 	return resp.LoadBalancers, err | ||||
| } | ||||
|  | ||||
| type commonResult struct { | ||||
| 	gophercloud.Result | ||||
| } | ||||
|  | ||||
| // Extract is a function that accepts a result and extracts a router. | ||||
| func (r commonResult) Extract() (*LoadBalancer, error) { | ||||
| 	if r.Err != nil { | ||||
| 		return nil, r.Err | ||||
| 	} | ||||
| 	var res struct { | ||||
| 		LoadBalancer *LoadBalancer `mapstructure:"loadbalancer" json:"loadbalancer"` | ||||
| 	} | ||||
| 	err := mapstructure.Decode(r.Body, &res) | ||||
|  | ||||
| 	return res.LoadBalancer, err | ||||
| } | ||||
|  | ||||
| // Extract is a function that accepts a result and extracts a Loadbalancer. | ||||
| func (r commonResult) ExtractStatuses() (*StatusTree, error) { | ||||
| 	if r.Err != nil { | ||||
| 		return nil, r.Err | ||||
| 	} | ||||
| 	var res struct { | ||||
| 		LoadBalancer *StatusTree `mapstructure:"statuses" json:"statuses"` | ||||
| 	} | ||||
| 	err := mapstructure.Decode(r.Body, &res) | ||||
|  | ||||
| 	return res.LoadBalancer, err | ||||
| } | ||||
|  | ||||
| // CreateResult represents the result of a create operation. | ||||
| type CreateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // GetResult represents the result of a get operation. | ||||
| type GetResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // UpdateResult represents the result of an update operation. | ||||
| type UpdateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // DeleteResult represents the result of a delete operation. | ||||
| type DeleteResult struct { | ||||
| 	gophercloud.ErrResult | ||||
| } | ||||
							
								
								
									
										21
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/urls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/loadbalancers/urls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| package loadbalancers | ||||
|  | ||||
| import "github.com/rackspace/gophercloud" | ||||
|  | ||||
| const ( | ||||
| 	rootPath     = "lbaas" | ||||
| 	resourcePath = "loadbalancers" | ||||
| 	statusPath   = "statuses" | ||||
| ) | ||||
|  | ||||
| func rootURL(c *gophercloud.ServiceClient) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath) | ||||
| } | ||||
|  | ||||
| func resourceURL(c *gophercloud.ServiceClient, id string) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath, id) | ||||
| } | ||||
|  | ||||
| func statusRootURL(c *gophercloud.ServiceClient, id string) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath, id, statusPath) | ||||
| } | ||||
							
								
								
									
										216
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/fixtures.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/fixtures.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,216 @@ | ||||
| // +build fixtures | ||||
|  | ||||
| package monitors | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"testing" | ||||
|  | ||||
| 	th "github.com/rackspace/gophercloud/testhelper" | ||||
| 	"github.com/rackspace/gophercloud/testhelper/client" | ||||
| ) | ||||
|  | ||||
| // HealthmonitorsListBody contains the canned body of a healthmonitor list response. | ||||
| const HealthmonitorsListBody = ` | ||||
| { | ||||
| 	"healthmonitors":[ | ||||
| 		{ | ||||
| 			"admin_state_up":true, | ||||
| 			"tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 			"delay":10, | ||||
| 			"name":"web", | ||||
| 			"max_retries":1, | ||||
| 			"timeout":1, | ||||
| 			"type":"PING", | ||||
| 			"pools": [{"id": "84f1b61f-58c4-45bf-a8a9-2dafb9e5214d"}], | ||||
| 			"id":"466c8345-28d8-4f84-a246-e04380b0461d" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"admin_state_up":true, | ||||
| 			"tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 			"delay":5, | ||||
| 			"name":"db", | ||||
| 			"expected_codes":"200", | ||||
| 			"max_retries":2, | ||||
| 			"http_method":"GET", | ||||
| 			"timeout":2, | ||||
| 			"url_path":"/", | ||||
| 			"type":"HTTP", | ||||
| 			"pools": [{"id": "d459f7d8-c6ee-439d-8713-d3fc08aeed8d"}], | ||||
| 			"id":"5d4b5228-33b0-4e60-b225-9b727c1a20e7" | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
| ` | ||||
|  | ||||
| // SingleHealthmonitorBody is the canned body of a Get request on an existing healthmonitor. | ||||
| const SingleHealthmonitorBody = ` | ||||
| { | ||||
| 	"healthmonitor": { | ||||
| 		"admin_state_up":true, | ||||
| 		"tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 		"delay":5, | ||||
| 		"name":"db", | ||||
| 		"expected_codes":"200", | ||||
| 		"max_retries":2, | ||||
| 		"http_method":"GET", | ||||
| 		"timeout":2, | ||||
| 		"url_path":"/", | ||||
| 		"type":"HTTP", | ||||
| 		"pools": [{"id": "d459f7d8-c6ee-439d-8713-d3fc08aeed8d"}], | ||||
| 		"id":"5d4b5228-33b0-4e60-b225-9b727c1a20e7" | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| // PostUpdateHealthmonitorBody is the canned response body of a Update request on an existing healthmonitor. | ||||
| const PostUpdateHealthmonitorBody = ` | ||||
| { | ||||
| 	"healthmonitor": { | ||||
| 		"admin_state_up":true, | ||||
| 		"tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 		"delay":3, | ||||
| 		"name":"NewHealthmonitorName", | ||||
| 		"expected_codes":"301", | ||||
| 		"max_retries":10, | ||||
| 		"http_method":"GET", | ||||
| 		"timeout":20, | ||||
| 		"url_path":"/another_check", | ||||
| 		"type":"HTTP", | ||||
| 		"pools": [{"id": "d459f7d8-c6ee-439d-8713-d3fc08aeed8d"}], | ||||
| 		"id":"5d4b5228-33b0-4e60-b225-9b727c1a20e7" | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| var ( | ||||
| 	HealthmonitorWeb = Monitor{ | ||||
| 		AdminStateUp: true, | ||||
| 		Name:         "web", | ||||
| 		TenantID:     "83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 		Delay:        10, | ||||
| 		MaxRetries:   1, | ||||
| 		Timeout:      1, | ||||
| 		Type:         "PING", | ||||
| 		ID:           "466c8345-28d8-4f84-a246-e04380b0461d", | ||||
| 		Pools:        []PoolID{{ID: "84f1b61f-58c4-45bf-a8a9-2dafb9e5214d"}}, | ||||
| 	} | ||||
| 	HealthmonitorDb = Monitor{ | ||||
| 		AdminStateUp:  true, | ||||
| 		Name:          "db", | ||||
| 		TenantID:      "83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 		Delay:         5, | ||||
| 		ExpectedCodes: "200", | ||||
| 		MaxRetries:    2, | ||||
| 		Timeout:       2, | ||||
| 		URLPath:       "/", | ||||
| 		Type:          "HTTP", | ||||
| 		HTTPMethod:    "GET", | ||||
| 		ID:            "5d4b5228-33b0-4e60-b225-9b727c1a20e7", | ||||
| 		Pools:         []PoolID{{ID: "d459f7d8-c6ee-439d-8713-d3fc08aeed8d"}}, | ||||
| 	} | ||||
| 	HealthmonitorUpdated = Monitor{ | ||||
| 		AdminStateUp:  true, | ||||
| 		Name:          "NewHealthmonitorName", | ||||
| 		TenantID:      "83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 		Delay:         3, | ||||
| 		ExpectedCodes: "301", | ||||
| 		MaxRetries:    10, | ||||
| 		Timeout:       20, | ||||
| 		URLPath:       "/another_check", | ||||
| 		Type:          "HTTP", | ||||
| 		HTTPMethod:    "GET", | ||||
| 		ID:            "5d4b5228-33b0-4e60-b225-9b727c1a20e7", | ||||
| 		Pools:         []PoolID{{ID: "d459f7d8-c6ee-439d-8713-d3fc08aeed8d"}}, | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // HandleHealthmonitorListSuccessfully sets up the test server to respond to a healthmonitor List request. | ||||
| func HandleHealthmonitorListSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/healthmonitors", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
|  | ||||
| 		w.Header().Add("Content-Type", "application/json") | ||||
| 		r.ParseForm() | ||||
| 		marker := r.Form.Get("marker") | ||||
| 		switch marker { | ||||
| 		case "": | ||||
| 			fmt.Fprintf(w, HealthmonitorsListBody) | ||||
| 		case "556c8345-28d8-4f84-a246-e04380b0461d": | ||||
| 			fmt.Fprintf(w, `{ "healthmonitors": [] }`) | ||||
| 		default: | ||||
| 			t.Fatalf("/v2.0/lbaas/healthmonitors invoked with unexpected marker=[%s]", marker) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleHealthmonitorCreationSuccessfully sets up the test server to respond to a healthmonitor creation request | ||||
| // with a given response. | ||||
| func HandleHealthmonitorCreationSuccessfully(t *testing.T, response string) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/healthmonitors", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "POST") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestJSONRequest(t, r, `{ | ||||
| 			"healthmonitor": { | ||||
| 				"type":"HTTP", | ||||
| 				"pool_id":"84f1b61f-58c4-45bf-a8a9-2dafb9e5214d", | ||||
| 				"tenant_id":"453105b9-1754-413f-aab1-55f1af620750", | ||||
| 				"delay":20, | ||||
| 				"name":"db", | ||||
| 				"timeout":10, | ||||
| 				"max_retries":5, | ||||
| 				"url_path":"/check", | ||||
| 				"expected_codes":"200-299" | ||||
| 			} | ||||
| 		}`) | ||||
|  | ||||
| 		w.WriteHeader(http.StatusAccepted) | ||||
| 		w.Header().Add("Content-Type", "application/json") | ||||
| 		fmt.Fprintf(w, response) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleHealthmonitorGetSuccessfully sets up the test server to respond to a healthmonitor Get request. | ||||
| func HandleHealthmonitorGetSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/healthmonitors/5d4b5228-33b0-4e60-b225-9b727c1a20e7", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
|  | ||||
| 		fmt.Fprintf(w, SingleHealthmonitorBody) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleHealthmonitorDeletionSuccessfully sets up the test server to respond to a healthmonitor deletion request. | ||||
| func HandleHealthmonitorDeletionSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/healthmonitors/5d4b5228-33b0-4e60-b225-9b727c1a20e7", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "DELETE") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
|  | ||||
| 		w.WriteHeader(http.StatusNoContent) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleHealthmonitorUpdateSuccessfully sets up the test server to respond to a healthmonitor Update request. | ||||
| func HandleHealthmonitorUpdateSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/healthmonitors/5d4b5228-33b0-4e60-b225-9b727c1a20e7", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "PUT") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
| 		th.TestHeader(t, r, "Content-Type", "application/json") | ||||
| 		th.TestJSONRequest(t, r, `{ | ||||
| 			"healthmonitor": { | ||||
| 				"name": "NewHealthmonitorName", | ||||
| 				"delay": 3, | ||||
| 				"timeout": 20, | ||||
| 				"max_retries": 10, | ||||
| 				"url_path": "/another_check", | ||||
| 				"expected_codes": "301" | ||||
| 			} | ||||
| 		}`) | ||||
|  | ||||
| 		fmt.Fprintf(w, PostUpdateHealthmonitorBody) | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										304
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/requests.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/requests.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,304 @@ | ||||
| package monitors | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/rackspace/gophercloud" | ||||
| 	"github.com/rackspace/gophercloud/pagination" | ||||
| ) | ||||
|  | ||||
| type monitorOpts struct { | ||||
| 	// Required. The Pool to Monitor. | ||||
| 	PoolID string | ||||
|  | ||||
| 	// Optional. The Name of the Monitor. | ||||
| 	Name string | ||||
|  | ||||
| 	// Required for admins. Indicates the owner of the Loadbalancer. | ||||
| 	TenantID string | ||||
|  | ||||
| 	// Required. 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 | ||||
|  | ||||
| 	// Required. The time, in seconds, between sending probes to members. | ||||
| 	Delay int | ||||
|  | ||||
| 	// 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 int | ||||
|  | ||||
| 	// Required. Number of permissible ping failures before changing the member's | ||||
| 	// status to INACTIVE. Must be a number between 1 and 10. | ||||
| 	MaxRetries int | ||||
|  | ||||
| 	// Required for HTTP(S) types. URI path that will be accessed if Monitor type | ||||
| 	// is HTTP or HTTPS. | ||||
| 	URLPath string | ||||
|  | ||||
| 	// 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 string | ||||
|  | ||||
| 	// 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 string | ||||
|  | ||||
| 	AdminStateUp *bool | ||||
| } | ||||
|  | ||||
| // ListOptsBuilder allows extensions to add additional parameters to the | ||||
| // List request. | ||||
| type ListOptsBuilder interface { | ||||
| 	ToMonitorListQuery() (string, error) | ||||
| } | ||||
|  | ||||
| // 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 Monitor attributes you want to see returned. SortKey allows you to | ||||
| // sort by a particular Monitor attribute. SortDir sets the direction, and is | ||||
| // either `asc' or `desc'. Marker and Limit are used for pagination. | ||||
| type ListOpts struct { | ||||
| 	ID            string `q:"id"` | ||||
| 	Name          string `q:"name"` | ||||
| 	TenantID      string `q:"tenant_id"` | ||||
| 	PoolID        string `q:"pool_id"` | ||||
| 	Type          string `q:"type"` | ||||
| 	Delay         int    `q:"delay"` | ||||
| 	Timeout       int    `q:"timeout"` | ||||
| 	MaxRetries    int    `q:"max_retries"` | ||||
| 	HTTPMethod    string `q:"http_method"` | ||||
| 	URLPath       string `q:"url_path"` | ||||
| 	ExpectedCodes string `q:"expected_codes"` | ||||
| 	AdminStateUp  *bool  `q:"admin_state_up"` | ||||
| 	Status        string `q:"status"` | ||||
| 	Limit         int    `q:"limit"` | ||||
| 	Marker        string `q:"marker"` | ||||
| 	SortKey       string `q:"sort_key"` | ||||
| 	SortDir       string `q:"sort_dir"` | ||||
| } | ||||
|  | ||||
| // ToMonitorListQuery formats a ListOpts into a query string. | ||||
| func (opts ListOpts) ToMonitorListQuery() (string, error) { | ||||
| 	q, err := gophercloud.BuildQueryString(opts) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return q.String(), nil | ||||
| } | ||||
|  | ||||
| // List returns a Pager which allows you to iterate over a collection of | ||||
| // health 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 health monitors 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 { | ||||
| 		query, err := opts.ToMonitorListQuery() | ||||
| 		if err != nil { | ||||
| 			return pagination.Pager{Err: err} | ||||
| 		} | ||||
| 		url += query | ||||
| 	} | ||||
|  | ||||
| 	return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { | ||||
| 		return MonitorPage{pagination.LinkedPageBase{PageResult: r}} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // Constants that represent approved monitoring types. | ||||
| const ( | ||||
| 	TypePING  = "PING" | ||||
| 	TypeTCP   = "TCP" | ||||
| 	TypeHTTP  = "HTTP" | ||||
| 	TypeHTTPS = "HTTPS" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	errPoolIDRequired        = fmt.Errorf("PoolID to monitor is required") | ||||
| 	errValidTypeRequired     = fmt.Errorf("A valid Type is required. Supported values are PING, TCP, HTTP and HTTPS") | ||||
| 	errDelayRequired         = fmt.Errorf("Delay is required") | ||||
| 	errTimeoutRequired       = fmt.Errorf("Timeout is required") | ||||
| 	errMaxRetriesRequired    = fmt.Errorf("MaxRetries is required") | ||||
| 	errURLPathRequired       = fmt.Errorf("URL path is required") | ||||
| 	errExpectedCodesRequired = fmt.Errorf("ExpectedCodes is required") | ||||
| 	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. | ||||
| type CreateOptsBuilder interface { | ||||
| 	ToMonitorCreateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // CreateOpts is the common options struct used in this package's Create | ||||
| // operation. | ||||
| type CreateOpts monitorOpts | ||||
|  | ||||
| // ToMonitorCreateMap casts a CreateOpts struct to a map. | ||||
| func (opts CreateOpts) ToMonitorCreateMap() (map[string]interface{}, error) { | ||||
| 	l := make(map[string]interface{}) | ||||
| 	allowed := map[string]bool{TypeHTTP: true, TypeHTTPS: true, TypeTCP: true, TypePING: true} | ||||
|  | ||||
| 	if allowed[opts.Type] { | ||||
| 		l["type"] = opts.Type | ||||
| 	} else { | ||||
| 		return nil, errValidTypeRequired | ||||
| 	} | ||||
| 	if opts.Type == TypeHTTP || opts.Type == TypeHTTPS { | ||||
| 		if opts.URLPath != "" { | ||||
| 			l["url_path"] = opts.URLPath | ||||
| 		} else { | ||||
| 			return nil, errURLPathRequired | ||||
| 		} | ||||
| 		if opts.ExpectedCodes != "" { | ||||
| 			l["expected_codes"] = opts.ExpectedCodes | ||||
| 		} else { | ||||
| 			return nil, errExpectedCodesRequired | ||||
| 		} | ||||
| 	} | ||||
| 	if opts.PoolID != "" { | ||||
| 		l["pool_id"] = opts.PoolID | ||||
| 	} else { | ||||
| 		return nil, errPoolIDRequired | ||||
| 	} | ||||
| 	if opts.Delay != 0 { | ||||
| 		l["delay"] = opts.Delay | ||||
| 	} else { | ||||
| 		return nil, errDelayRequired | ||||
| 	} | ||||
| 	if opts.Timeout != 0 { | ||||
| 		l["timeout"] = opts.Timeout | ||||
| 	} else { | ||||
| 		return nil, errMaxRetriesRequired | ||||
| 	} | ||||
| 	if opts.MaxRetries != 0 { | ||||
| 		l["max_retries"] = opts.MaxRetries | ||||
| 	} else { | ||||
| 		return nil, errMaxRetriesRequired | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		l["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
| 	if opts.Name != "" { | ||||
| 		l["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.TenantID != "" { | ||||
| 		l["tenant_id"] = opts.TenantID | ||||
| 	} | ||||
| 	if opts.HTTPMethod != "" { | ||||
| 		l["http_method"] = opts.HTTPMethod | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"healthmonitor": l}, nil | ||||
| } | ||||
|  | ||||
| /* | ||||
|  Create is an operation which provisions a new Health Monitor. There are | ||||
|  different types of Monitor you can provision: PING, TCP or HTTP(S). Below | ||||
|  are examples of how to create each one. | ||||
|  | ||||
|  Here is an example config struct to use when creating a PING or TCP Monitor: | ||||
|  | ||||
|  CreateOpts{Type: TypePING, Delay: 20, Timeout: 10, MaxRetries: 3} | ||||
|  CreateOpts{Type: TypeTCP, Delay: 20, Timeout: 10, MaxRetries: 3} | ||||
|  | ||||
|  Here is an example config struct to use when creating a HTTP(S) Monitor: | ||||
|  | ||||
|  CreateOpts{Type: TypeHTTP, Delay: 20, Timeout: 10, MaxRetries: 3, | ||||
|  HttpMethod: "HEAD", ExpectedCodes: "200", PoolID: "2c946bfc-1804-43ab-a2ff-58f6a762b505"} | ||||
| */ | ||||
|  | ||||
| func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { | ||||
| 	var res CreateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToMonitorCreateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	// Send request to API | ||||
| 	_, res.Err = c.Post(rootURL(c), reqBody, &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // Get retrieves a particular Health Monitor based on its unique ID. | ||||
| func Get(c *gophercloud.ServiceClient, id string) GetResult { | ||||
| 	var res GetResult | ||||
| 	_, res.Err = c.Get(resourceURL(c, id), &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // 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. | ||||
| type UpdateOptsBuilder interface { | ||||
| 	ToMonitorUpdateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // UpdateOpts is the common options struct used in this package's Update | ||||
| // operation. | ||||
| type UpdateOpts monitorOpts | ||||
|  | ||||
| // ToMonitorUpdateMap casts a UpdateOpts struct to a map. | ||||
| func (opts UpdateOpts) ToMonitorUpdateMap() (map[string]interface{}, error) { | ||||
| 	l := make(map[string]interface{}) | ||||
|  | ||||
| 	if opts.URLPath != "" { | ||||
| 		l["url_path"] = opts.URLPath | ||||
| 	} | ||||
| 	if opts.ExpectedCodes != "" { | ||||
| 		l["expected_codes"] = opts.ExpectedCodes | ||||
| 	} | ||||
| 	if opts.Delay != 0 { | ||||
| 		l["delay"] = opts.Delay | ||||
| 	} | ||||
| 	if opts.Timeout != 0 { | ||||
| 		l["timeout"] = opts.Timeout | ||||
| 	} | ||||
| 	if opts.MaxRetries != 0 { | ||||
| 		l["max_retries"] = opts.MaxRetries | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		l["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
| 	if opts.Name != "" { | ||||
| 		l["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.HTTPMethod != "" { | ||||
| 		l["http_method"] = opts.HTTPMethod | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"healthmonitor": l}, nil | ||||
| } | ||||
|  | ||||
| // Update is an operation which modifies the attributes of the specified Monitor. | ||||
| func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { | ||||
| 	var res UpdateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToMonitorUpdateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	// Send request to API | ||||
| 	_, res.Err = c.Put(resourceURL(c, id), reqBody, &res.Body, &gophercloud.RequestOpts{ | ||||
| 		OkCodes: []int{200, 202}, | ||||
| 	}) | ||||
|  | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // Delete will permanently delete a particular Monitor based on its unique ID. | ||||
| func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { | ||||
| 	var res DeleteResult | ||||
| 	_, res.Err = c.Delete(resourceURL(c, id), nil) | ||||
| 	return res | ||||
| } | ||||
							
								
								
									
										160
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/results.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/results.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,160 @@ | ||||
| package monitors | ||||
|  | ||||
| import ( | ||||
| 	"github.com/mitchellh/mapstructure" | ||||
| 	"github.com/rackspace/gophercloud" | ||||
| 	"github.com/rackspace/gophercloud/pagination" | ||||
| ) | ||||
|  | ||||
| type PoolID struct { | ||||
| 	ID string `mapstructure:"id" json:"id"` | ||||
| } | ||||
|  | ||||
| // Monitor represents a load balancer health monitor. A health monitor is used | ||||
| // to determine whether or not back-end members of the VIP's pool are usable | ||||
| // for processing a request. A pool can have several health monitors associated | ||||
| // with it. There are different types of health monitors supported: | ||||
| // | ||||
| // PING: used to ping the members using ICMP. | ||||
| // TCP: used to connect to the members using TCP. | ||||
| // HTTP: used to send an HTTP request to the member. | ||||
| // HTTPS: used to send a secure HTTP request to the member. | ||||
| // | ||||
| // When a pool has several monitors associated with it, each member of the pool | ||||
| // is monitored by all these monitors. If any monitor declares the member as | ||||
| // unhealthy, then the member status is changed to INACTIVE and the member | ||||
| // 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 Monitor. | ||||
| 	ID string | ||||
|  | ||||
| 	// The Name of the Monitor. | ||||
| 	Name string | ||||
|  | ||||
| 	// Only an administrative user can specify a tenant ID | ||||
| 	// other than its own. | ||||
| 	TenantID string `json:"tenant_id" mapstructure:"tenant_id"` | ||||
|  | ||||
| 	// 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 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 int | ||||
|  | ||||
| 	// 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" mapstructure:"max_retries"` | ||||
|  | ||||
| 	// The HTTP method that the monitor uses for requests. | ||||
| 	HTTPMethod string `json:"http_method" mapstructure:"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 string `json:"url_path" mapstructure:"url_path"` | ||||
|  | ||||
| 	// Expected HTTP codes for a passing HTTP(S) monitor. | ||||
| 	ExpectedCodes string `json:"expected_codes" mapstructure:"expected_codes"` | ||||
|  | ||||
| 	// The administrative state of the health monitor, which is up (true) or down (false). | ||||
| 	AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"` | ||||
|  | ||||
| 	// The status of the health monitor. Indicates whether the health monitor is | ||||
| 	// operational. | ||||
| 	Status string | ||||
|  | ||||
| 	// List of pools that are associated with the health monitor. | ||||
| 	Pools []PoolID `mapstructure:"pools" json:"pools"` | ||||
| } | ||||
|  | ||||
| type Pool struct { | ||||
| } | ||||
|  | ||||
| // MonitorPage is the page returned by a pager when traversing over a | ||||
| // collection of health monitors. | ||||
| type MonitorPage struct { | ||||
| 	pagination.LinkedPageBase | ||||
| } | ||||
|  | ||||
| // NextPageURL is invoked when a paginated collection of monitors 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 (p MonitorPage) NextPageURL() (string, error) { | ||||
| 	type resp struct { | ||||
| 		Links []gophercloud.Link `mapstructure:"healthmonitors_links"` | ||||
| 	} | ||||
|  | ||||
| 	var r resp | ||||
| 	err := mapstructure.Decode(p.Body, &r) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return gophercloud.ExtractNextURL(r.Links) | ||||
| } | ||||
|  | ||||
| // IsEmpty checks whether a PoolPage struct is empty. | ||||
| func (p MonitorPage) IsEmpty() (bool, error) { | ||||
| 	is, err := ExtractMonitors(p) | ||||
| 	if err != nil { | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return len(is) == 0, nil | ||||
| } | ||||
|  | ||||
| // ExtractMonitors accepts a Page struct, specifically a MonitorPage struct, | ||||
| // and extracts the elements into a slice of Monitor structs. In other words, | ||||
| // a generic collection is mapped into a relevant slice. | ||||
| func ExtractMonitors(page pagination.Page) ([]Monitor, error) { | ||||
| 	var resp struct { | ||||
| 		Monitors []Monitor `mapstructure:"healthmonitors" json:"healthmonitors"` | ||||
| 	} | ||||
|  | ||||
| 	err := mapstructure.Decode(page.(MonitorPage).Body, &resp) | ||||
|  | ||||
| 	return resp.Monitors, err | ||||
| } | ||||
|  | ||||
| type commonResult struct { | ||||
| 	gophercloud.Result | ||||
| } | ||||
|  | ||||
| // Extract is a function that accepts a result and extracts a monitor. | ||||
| func (r commonResult) Extract() (*Monitor, error) { | ||||
| 	if r.Err != nil { | ||||
| 		return nil, r.Err | ||||
| 	} | ||||
|  | ||||
| 	var res struct { | ||||
| 		Monitor *Monitor `json:"healthmonitor" mapstructure:"healthmonitor"` | ||||
| 	} | ||||
|  | ||||
| 	err := mapstructure.Decode(r.Body, &res) | ||||
|  | ||||
| 	return res.Monitor, err | ||||
| } | ||||
|  | ||||
| // CreateResult represents the result of a create operation. | ||||
| type CreateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // GetResult represents the result of a get operation. | ||||
| type GetResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // UpdateResult represents the result of an update operation. | ||||
| type UpdateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // DeleteResult represents the result of a delete operation. | ||||
| type DeleteResult struct { | ||||
| 	gophercloud.ErrResult | ||||
| } | ||||
							
								
								
									
										16
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/urls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors/urls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| package monitors | ||||
|  | ||||
| import "github.com/rackspace/gophercloud" | ||||
|  | ||||
| const ( | ||||
| 	rootPath     = "lbaas" | ||||
| 	resourcePath = "healthmonitors" | ||||
| ) | ||||
|  | ||||
| func rootURL(c *gophercloud.ServiceClient) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath) | ||||
| } | ||||
|  | ||||
| func resourceURL(c *gophercloud.ServiceClient, id string) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath, id) | ||||
| } | ||||
							
								
								
									
										389
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/fixtures.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										389
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/fixtures.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,389 @@ | ||||
| // +build fixtures | ||||
|  | ||||
| package pools | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"testing" | ||||
|  | ||||
| 	th "github.com/rackspace/gophercloud/testhelper" | ||||
| 	"github.com/rackspace/gophercloud/testhelper/client" | ||||
| ) | ||||
|  | ||||
| // PoolsListBody contains the canned body of a pool list response. | ||||
| const PoolsListBody = ` | ||||
| { | ||||
| 	"pools":[ | ||||
| 	         { | ||||
| 			"lb_algorithm":"ROUND_ROBIN", | ||||
| 			"protocol":"HTTP", | ||||
| 			"description":"", | ||||
| 			"healthmonitor_id": "466c8345-28d8-4f84-a246-e04380b0461d", | ||||
| 			"members":[{"id": "53306cda-815d-4354-9fe4-59e09da9c3c5"}], | ||||
| 			"listeners":[{"id": "2a280670-c202-4b0b-a562-34077415aabf"}], | ||||
| 			"loadbalancers":[{"id": "79e05663-7f03-45d2-a092-8b94062f22ab"}], | ||||
| 			"id":"72741b06-df4d-4715-b142-276b6bce75ab", | ||||
| 			"name":"web", | ||||
| 			"admin_state_up":true, | ||||
| 			"tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 			"provider": "haproxy" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"lb_algorithm":"LEAST_CONNECTION", | ||||
| 			"protocol":"HTTP", | ||||
| 			"description":"", | ||||
| 			"healthmonitor_id": "5f6c8345-28d8-4f84-a246-e04380b0461d", | ||||
| 			"members":[{"id": "67306cda-815d-4354-9fe4-59e09da9c3c5"}], | ||||
| 			"listeners":[{"id": "2a280670-c202-4b0b-a562-34077415aabf"}], | ||||
| 			"loadbalancers":[{"id": "79e05663-7f03-45d2-a092-8b94062f22ab"}], | ||||
| 			"id":"c3741b06-df4d-4715-b142-276b6bce75ab", | ||||
| 			"name":"db", | ||||
| 			"admin_state_up":true, | ||||
| 			"tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 			"provider": "haproxy" | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
| ` | ||||
|  | ||||
| // SinglePoolBody is the canned body of a Get request on an existing pool. | ||||
| const SinglePoolBody = ` | ||||
| { | ||||
| 	"pool": { | ||||
| 		"lb_algorithm":"LEAST_CONNECTION", | ||||
| 		"protocol":"HTTP", | ||||
| 		"description":"", | ||||
| 		"healthmonitor_id": "5f6c8345-28d8-4f84-a246-e04380b0461d", | ||||
| 		"members":[{"id": "67306cda-815d-4354-9fe4-59e09da9c3c5"}], | ||||
| 		"listeners":[{"id": "2a280670-c202-4b0b-a562-34077415aabf"}], | ||||
| 		"loadbalancers":[{"id": "79e05663-7f03-45d2-a092-8b94062f22ab"}], | ||||
| 		"id":"c3741b06-df4d-4715-b142-276b6bce75ab", | ||||
| 		"name":"db", | ||||
| 		"admin_state_up":true, | ||||
| 		"tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 		"provider": "haproxy" | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| // PostUpdatePoolBody is the canned response body of a Update request on an existing pool. | ||||
| const PostUpdatePoolBody = ` | ||||
| { | ||||
| 	"pool": { | ||||
| 		"lb_algorithm":"LEAST_CONNECTION", | ||||
| 		"protocol":"HTTP", | ||||
| 		"description":"", | ||||
| 		"healthmonitor_id": "5f6c8345-28d8-4f84-a246-e04380b0461d", | ||||
| 		"members":[{"id": "67306cda-815d-4354-9fe4-59e09da9c3c5"}], | ||||
| 		"listeners":[{"id": "2a280670-c202-4b0b-a562-34077415aabf"}], | ||||
| 		"loadbalancers":[{"id": "79e05663-7f03-45d2-a092-8b94062f22ab"}], | ||||
| 		"id":"c3741b06-df4d-4715-b142-276b6bce75ab", | ||||
| 		"name":"db", | ||||
| 		"admin_state_up":true, | ||||
| 		"tenant_id":"83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 		"provider": "haproxy" | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| var ( | ||||
| 	PoolWeb = Pool{ | ||||
| 		LBMethod:      "ROUND_ROBIN", | ||||
| 		Protocol:      "HTTP", | ||||
| 		Description:   "", | ||||
| 		MonitorID:     "466c8345-28d8-4f84-a246-e04380b0461d", | ||||
| 		TenantID:      "83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 		AdminStateUp:  true, | ||||
| 		Name:          "web", | ||||
| 		Members:       []Member{{ID: "53306cda-815d-4354-9fe4-59e09da9c3c5"}}, | ||||
| 		ID:            "72741b06-df4d-4715-b142-276b6bce75ab", | ||||
| 		Loadbalancers: []LoadBalancerID{{ID: "79e05663-7f03-45d2-a092-8b94062f22ab"}}, | ||||
| 		Listeners:     []ListenerID{{ID: "2a280670-c202-4b0b-a562-34077415aabf"}}, | ||||
| 		Provider:      "haproxy", | ||||
| 	} | ||||
| 	PoolDb = Pool{ | ||||
| 		LBMethod:      "LEAST_CONNECTION", | ||||
| 		Protocol:      "HTTP", | ||||
| 		Description:   "", | ||||
| 		MonitorID:     "5f6c8345-28d8-4f84-a246-e04380b0461d", | ||||
| 		TenantID:      "83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 		AdminStateUp:  true, | ||||
| 		Name:          "db", | ||||
| 		Members:       []Member{{ID: "67306cda-815d-4354-9fe4-59e09da9c3c5"}}, | ||||
| 		ID:            "c3741b06-df4d-4715-b142-276b6bce75ab", | ||||
| 		Loadbalancers: []LoadBalancerID{{ID: "79e05663-7f03-45d2-a092-8b94062f22ab"}}, | ||||
| 		Listeners:     []ListenerID{{ID: "2a280670-c202-4b0b-a562-34077415aabf"}}, | ||||
| 		Provider:      "haproxy", | ||||
| 	} | ||||
| 	PoolUpdated = Pool{ | ||||
| 		LBMethod:      "LEAST_CONNECTION", | ||||
| 		Protocol:      "HTTP", | ||||
| 		Description:   "", | ||||
| 		MonitorID:     "5f6c8345-28d8-4f84-a246-e04380b0461d", | ||||
| 		TenantID:      "83657cfcdfe44cd5920adaf26c48ceea", | ||||
| 		AdminStateUp:  true, | ||||
| 		Name:          "db", | ||||
| 		Members:       []Member{{ID: "67306cda-815d-4354-9fe4-59e09da9c3c5"}}, | ||||
| 		ID:            "c3741b06-df4d-4715-b142-276b6bce75ab", | ||||
| 		Loadbalancers: []LoadBalancerID{{ID: "79e05663-7f03-45d2-a092-8b94062f22ab"}}, | ||||
| 		Listeners:     []ListenerID{{ID: "2a280670-c202-4b0b-a562-34077415aabf"}}, | ||||
| 		Provider:      "haproxy", | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // HandlePoolListSuccessfully sets up the test server to respond to a pool List request. | ||||
| func HandlePoolListSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/pools", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
|  | ||||
| 		w.Header().Add("Content-Type", "application/json") | ||||
| 		r.ParseForm() | ||||
| 		marker := r.Form.Get("marker") | ||||
| 		switch marker { | ||||
| 		case "": | ||||
| 			fmt.Fprintf(w, PoolsListBody) | ||||
| 		case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab": | ||||
| 			fmt.Fprintf(w, `{ "pools": [] }`) | ||||
| 		default: | ||||
| 			t.Fatalf("/v2.0/lbaas/pools invoked with unexpected marker=[%s]", marker) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandlePoolCreationSuccessfully sets up the test server to respond to a pool creation request | ||||
| // with a given response. | ||||
| func HandlePoolCreationSuccessfully(t *testing.T, response string) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/pools", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "POST") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestJSONRequest(t, r, `{ | ||||
| 			"pool": { | ||||
| 			        "lb_algorithm": "ROUND_ROBIN", | ||||
| 			        "protocol": "HTTP", | ||||
| 			        "name": "Example pool", | ||||
| 			        "tenant_id": "2ffc6e22aae24e4795f87155d24c896f", | ||||
| 			        "loadbalancer_id": "79e05663-7f03-45d2-a092-8b94062f22ab" | ||||
| 			} | ||||
| 		}`) | ||||
|  | ||||
| 		w.WriteHeader(http.StatusAccepted) | ||||
| 		w.Header().Add("Content-Type", "application/json") | ||||
| 		fmt.Fprintf(w, response) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandlePoolGetSuccessfully sets up the test server to respond to a pool Get request. | ||||
| func HandlePoolGetSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/pools/c3741b06-df4d-4715-b142-276b6bce75ab", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
|  | ||||
| 		fmt.Fprintf(w, SinglePoolBody) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandlePoolDeletionSuccessfully sets up the test server to respond to a pool deletion request. | ||||
| func HandlePoolDeletionSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/pools/c3741b06-df4d-4715-b142-276b6bce75ab", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "DELETE") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
|  | ||||
| 		w.WriteHeader(http.StatusNoContent) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandlePoolUpdateSuccessfully sets up the test server to respond to a pool Update request. | ||||
| func HandlePoolUpdateSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/pools/c3741b06-df4d-4715-b142-276b6bce75ab", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "PUT") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
| 		th.TestHeader(t, r, "Content-Type", "application/json") | ||||
| 		th.TestJSONRequest(t, r, `{ | ||||
| 			"pool": { | ||||
| 				"name": "NewPoolName", | ||||
|                                 "lb_algorithm": "LEAST_CONNECTIONS" | ||||
| 			} | ||||
| 		}`) | ||||
|  | ||||
| 		fmt.Fprintf(w, PostUpdatePoolBody) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // MembersListBody contains the canned body of a member list response. | ||||
| const MembersListBody = ` | ||||
| { | ||||
| 	"members":[ | ||||
| 		{ | ||||
| 			"id": "2a280670-c202-4b0b-a562-34077415aabf", | ||||
| 			"address": "10.0.2.10", | ||||
| 			"weight": 5, | ||||
| 			"name": "web", | ||||
| 			"subnet_id": "1981f108-3c48-48d2-b908-30f7d28532c9", | ||||
| 			"tenant_id": "2ffc6e22aae24e4795f87155d24c896f", | ||||
| 			"admin_state_up":true, | ||||
| 			"protocol_port": 80 | ||||
| 		}, | ||||
| 		{ | ||||
| 			"id": "fad389a3-9a4a-4762-a365-8c7038508b5d", | ||||
| 			"address": "10.0.2.11", | ||||
| 			"weight": 10, | ||||
| 			"name": "db", | ||||
| 			"subnet_id": "1981f108-3c48-48d2-b908-30f7d28532c9", | ||||
| 			"tenant_id": "2ffc6e22aae24e4795f87155d24c896f", | ||||
| 			"admin_state_up":false, | ||||
| 			"protocol_port": 80 | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
| ` | ||||
|  | ||||
| // SingleMemberBody is the canned body of a Get request on an existing member. | ||||
| const SingleMemberBody = ` | ||||
| { | ||||
| 	"member": { | ||||
| 		"id": "fad389a3-9a4a-4762-a365-8c7038508b5d", | ||||
| 		"address": "10.0.2.11", | ||||
| 		"weight": 10, | ||||
| 		"name": "db", | ||||
| 		"subnet_id": "1981f108-3c48-48d2-b908-30f7d28532c9", | ||||
| 		"tenant_id": "2ffc6e22aae24e4795f87155d24c896f", | ||||
| 		"admin_state_up":false, | ||||
| 		"protocol_port": 80 | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| // PostUpdateMemberBody is the canned response body of a Update request on an existing member. | ||||
| const PostUpdateMemberBody = ` | ||||
| { | ||||
| 	"member": { | ||||
| 		"id": "fad389a3-9a4a-4762-a365-8c7038508b5d", | ||||
| 		"address": "10.0.2.11", | ||||
| 		"weight": 10, | ||||
| 		"name": "db", | ||||
| 		"subnet_id": "1981f108-3c48-48d2-b908-30f7d28532c9", | ||||
| 		"tenant_id": "2ffc6e22aae24e4795f87155d24c896f", | ||||
| 		"admin_state_up":false, | ||||
| 		"protocol_port": 80 | ||||
| 	} | ||||
| } | ||||
| ` | ||||
|  | ||||
| var ( | ||||
| 	MemberWeb = Member{ | ||||
| 		SubnetID:     "1981f108-3c48-48d2-b908-30f7d28532c9", | ||||
| 		TenantID:     "2ffc6e22aae24e4795f87155d24c896f", | ||||
| 		AdminStateUp: true, | ||||
| 		Name:         "web", | ||||
| 		ID:           "2a280670-c202-4b0b-a562-34077415aabf", | ||||
| 		Address:      "10.0.2.10", | ||||
| 		Weight:       5, | ||||
| 		ProtocolPort: 80, | ||||
| 	} | ||||
| 	MemberDb = Member{ | ||||
| 		SubnetID:     "1981f108-3c48-48d2-b908-30f7d28532c9", | ||||
| 		TenantID:     "2ffc6e22aae24e4795f87155d24c896f", | ||||
| 		AdminStateUp: false, | ||||
| 		Name:         "db", | ||||
| 		ID:           "fad389a3-9a4a-4762-a365-8c7038508b5d", | ||||
| 		Address:      "10.0.2.11", | ||||
| 		Weight:       10, | ||||
| 		ProtocolPort: 80, | ||||
| 	} | ||||
| 	MemberUpdated = Member{ | ||||
| 		SubnetID:     "1981f108-3c48-48d2-b908-30f7d28532c9", | ||||
| 		TenantID:     "2ffc6e22aae24e4795f87155d24c896f", | ||||
| 		AdminStateUp: false, | ||||
| 		Name:         "db", | ||||
| 		ID:           "fad389a3-9a4a-4762-a365-8c7038508b5d", | ||||
| 		Address:      "10.0.2.11", | ||||
| 		Weight:       10, | ||||
| 		ProtocolPort: 80, | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| // HandleMemberListSuccessfully sets up the test server to respond to a member List request. | ||||
| func HandleMemberListSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
|  | ||||
| 		w.Header().Add("Content-Type", "application/json") | ||||
| 		r.ParseForm() | ||||
| 		marker := r.Form.Get("marker") | ||||
| 		switch marker { | ||||
| 		case "": | ||||
| 			fmt.Fprintf(w, MembersListBody) | ||||
| 		case "45e08a3e-a78f-4b40-a229-1e7e23eee1ab": | ||||
| 			fmt.Fprintf(w, `{ "members": [] }`) | ||||
| 		default: | ||||
| 			t.Fatalf("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members invoked with unexpected marker=[%s]", marker) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleMemberCreationSuccessfully sets up the test server to respond to a member creation request | ||||
| // with a given response. | ||||
| func HandleMemberCreationSuccessfully(t *testing.T, response string) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "POST") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestJSONRequest(t, r, `{ | ||||
| 			"member": { | ||||
| 			        "address": "10.0.2.11", | ||||
| 			        "weight": 10, | ||||
| 			        "name": "db", | ||||
| 			        "subnet_id": "1981f108-3c48-48d2-b908-30f7d28532c9", | ||||
| 			        "tenant_id": "2ffc6e22aae24e4795f87155d24c896f", | ||||
| 			        "protocol_port": 80 | ||||
| 			} | ||||
| 		}`) | ||||
|  | ||||
| 		w.WriteHeader(http.StatusAccepted) | ||||
| 		w.Header().Add("Content-Type", "application/json") | ||||
| 		fmt.Fprintf(w, response) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleMemberGetSuccessfully sets up the test server to respond to a member Get request. | ||||
| func HandleMemberGetSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members/2a280670-c202-4b0b-a562-34077415aabf", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "GET") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
|  | ||||
| 		fmt.Fprintf(w, SingleMemberBody) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleMemberDeletionSuccessfully sets up the test server to respond to a member deletion request. | ||||
| func HandleMemberDeletionSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members/2a280670-c202-4b0b-a562-34077415aabf", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "DELETE") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
|  | ||||
| 		w.WriteHeader(http.StatusNoContent) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // HandleMemberUpdateSuccessfully sets up the test server to respond to a member Update request. | ||||
| func HandleMemberUpdateSuccessfully(t *testing.T) { | ||||
| 	th.Mux.HandleFunc("/v2.0/lbaas/pools/332abe93-f488-41ba-870b-2ac66be7f853/members/2a280670-c202-4b0b-a562-34077415aabf", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		th.TestMethod(t, r, "PUT") | ||||
| 		th.TestHeader(t, r, "X-Auth-Token", client.TokenID) | ||||
| 		th.TestHeader(t, r, "Accept", "application/json") | ||||
| 		th.TestHeader(t, r, "Content-Type", "application/json") | ||||
| 		th.TestJSONRequest(t, r, `{ | ||||
| 			"member": { | ||||
| 				"name": "newMemberName", | ||||
|                                 "weight": 4 | ||||
| 			} | ||||
| 		}`) | ||||
|  | ||||
| 		fmt.Fprintf(w, PostUpdateMemberBody) | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										485
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/requests.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										485
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/requests.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,485 @@ | ||||
| package pools | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/rackspace/gophercloud" | ||||
| 	"github.com/rackspace/gophercloud/pagination" | ||||
| ) | ||||
|  | ||||
| // AdminState gives users a solid type to work with for create and update | ||||
| // operations. It is recommended that users use the `Up` and `Down` enums. | ||||
| type AdminState *bool | ||||
|  | ||||
| type poolOpts struct { | ||||
| 	// Only required if the caller has an admin role and wants to create a pool | ||||
| 	// for another tenant. | ||||
| 	TenantID string | ||||
|  | ||||
| 	// Optional. Name of the pool. | ||||
| 	Name string | ||||
|  | ||||
| 	// Optional. Human-readable description for the pool. | ||||
| 	Description string | ||||
|  | ||||
| 	// Required. The protocol used by the pool members, you can use either | ||||
| 	// ProtocolTCP, ProtocolHTTP, or ProtocolHTTPS. | ||||
| 	Protocol Protocol | ||||
|  | ||||
| 	// The Loadbalancer on which the members of the pool will be associated with. | ||||
| 	// Note:  one of LoadbalancerID or ListenerID must be provided. | ||||
| 	LoadbalancerID string | ||||
|  | ||||
| 	// The Listener on which the members of the pool will be associated with. | ||||
| 	// Note:  one of LoadbalancerID or ListenerID must be provided. | ||||
| 	ListenerID string | ||||
|  | ||||
| 	// Required. 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 | ||||
|  | ||||
| 	// Optional. Omit this field to prevent session persistence. | ||||
| 	Persistence *SessionPersistence | ||||
|  | ||||
| 	// Optional. The administrative state of the Pool. A valid value is true (UP) | ||||
| 	// or false (DOWN). | ||||
| 	AdminStateUp *bool | ||||
| } | ||||
|  | ||||
| // Convenience vars for AdminStateUp values. | ||||
| var ( | ||||
| 	iTrue  = true | ||||
| 	iFalse = false | ||||
|  | ||||
| 	Up   AdminState = &iTrue | ||||
| 	Down AdminState = &iFalse | ||||
| ) | ||||
|  | ||||
| // ListOptsBuilder allows extensions to add additional parameters to the | ||||
| // List request. | ||||
| type ListOptsBuilder interface { | ||||
| 	ToPoolListQuery() (string, error) | ||||
| } | ||||
|  | ||||
| // 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 Pool attributes you want to see returned. SortKey allows you to | ||||
| // sort by a particular Pool attribute. SortDir sets the direction, and is | ||||
| // either `asc' or `desc'. Marker and Limit are used for pagination. | ||||
| type ListOpts struct { | ||||
| 	LBMethod       string `q:"lb_algorithm"` | ||||
| 	Protocol       string `q:"protocol"` | ||||
| 	TenantID       string `q:"tenant_id"` | ||||
| 	AdminStateUp   *bool  `q:"admin_state_up"` | ||||
| 	Name           string `q:"name"` | ||||
| 	ID             string `q:"id"` | ||||
| 	LoadbalancerID string `q:"loadbalancer_id"` | ||||
| 	ListenerID     string `q:"listener_id"` | ||||
| 	Limit          int    `q:"limit"` | ||||
| 	Marker         string `q:"marker"` | ||||
| 	SortKey        string `q:"sort_key"` | ||||
| 	SortDir        string `q:"sort_dir"` | ||||
| } | ||||
|  | ||||
| // ToPoolListQuery formats a ListOpts into a query string. | ||||
| func (opts ListOpts) ToPoolListQuery() (string, error) { | ||||
| 	q, err := gophercloud.BuildQueryString(opts) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return q.String(), nil | ||||
| } | ||||
|  | ||||
| // 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 | ||||
| // the returned collection for greater efficiency. | ||||
| // | ||||
| // Default policy settings return only those pools 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 { | ||||
| 		query, err := opts.ToPoolListQuery() | ||||
| 		if err != nil { | ||||
| 			return pagination.Pager{Err: err} | ||||
| 		} | ||||
| 		url += query | ||||
| 	} | ||||
|  | ||||
| 	return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { | ||||
| 		return PoolPage{pagination.LinkedPageBase{PageResult: r}} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| type LBMethod string | ||||
| type Protocol string | ||||
|  | ||||
| // Supported attributes for create/update operations. | ||||
| const ( | ||||
| 	LBMethodRoundRobin       LBMethod = "ROUND_ROBIN" | ||||
| 	LBMethodLeastConnections LBMethod = "LEAST_CONNECTIONS" | ||||
| 	LBMethodSourceIp         LBMethod = "SOURCE_IP" | ||||
|  | ||||
| 	ProtocolTCP   Protocol = "TCP" | ||||
| 	ProtocolHTTP  Protocol = "HTTP" | ||||
| 	ProtocolHTTPS Protocol = "HTTPS" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	errLoadbalancerOrListenerRequired = fmt.Errorf("A ListenerID or LoadbalancerID is required") | ||||
| 	errValidLBMethodRequired          = fmt.Errorf("A valid LBMethod is required. Supported values are ROUND_ROBIN, LEAST_CONNECTIONS, SOURCE_IP") | ||||
| 	errValidProtocolRequired          = fmt.Errorf("A valid Protocol is required. Supported values are TCP, HTTP, 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. | ||||
| type CreateOptsBuilder interface { | ||||
| 	ToPoolCreateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // CreateOpts is the common options struct used in this package's Create | ||||
| // operation. | ||||
| type CreateOpts poolOpts | ||||
|  | ||||
| // ToPoolCreateMap casts a CreateOpts struct to a map. | ||||
| func (opts CreateOpts) ToPoolCreateMap() (map[string]interface{}, error) { | ||||
| 	l := make(map[string]interface{}) | ||||
| 	allowedLBMethod := map[LBMethod]bool{LBMethodRoundRobin: true, LBMethodLeastConnections: true, LBMethodSourceIp: true} | ||||
| 	allowedProtocol := map[Protocol]bool{ProtocolTCP: true, ProtocolHTTP: true, ProtocolHTTPS: true} | ||||
|  | ||||
| 	if allowedLBMethod[opts.LBMethod] { | ||||
| 		l["lb_algorithm"] = opts.LBMethod | ||||
| 	} else { | ||||
| 		return nil, errValidLBMethodRequired | ||||
| 	} | ||||
| 	if allowedProtocol[opts.Protocol] { | ||||
| 		l["protocol"] = opts.Protocol | ||||
| 	} else { | ||||
| 		return nil, errValidProtocolRequired | ||||
| 	} | ||||
| 	if opts.LoadbalancerID == "" && opts.ListenerID == "" { | ||||
| 		return nil, errLoadbalancerOrListenerRequired | ||||
| 	} else { | ||||
| 		if opts.LoadbalancerID != "" { | ||||
| 			l["loadbalancer_id"] = opts.LoadbalancerID | ||||
| 		} | ||||
| 		if opts.ListenerID != "" { | ||||
| 			l["listener_id"] = opts.ListenerID | ||||
| 		} | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		l["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
| 	if opts.Name != "" { | ||||
| 		l["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.TenantID != "" { | ||||
| 		l["tenant_id"] = opts.TenantID | ||||
| 	} | ||||
| 	if opts.Persistence != nil { | ||||
| 		l["session_persistence"] = &opts.Persistence | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"pool": l}, nil | ||||
| } | ||||
|  | ||||
| // Create accepts a CreateOpts struct and uses the values to create a new | ||||
| // load balancer pool. | ||||
| func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult { | ||||
| 	var res CreateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToPoolCreateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	// Send request to API | ||||
| 	_, res.Err = c.Post(rootURL(c), reqBody, &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // Get retrieves a particular pool based on its unique ID. | ||||
| func Get(c *gophercloud.ServiceClient, id string) GetResult { | ||||
| 	var res GetResult | ||||
| 	_, res.Err = c.Get(resourceURL(c, id), &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // 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. | ||||
| type UpdateOptsBuilder interface { | ||||
| 	ToPoolUpdateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // UpdateOpts is the common options struct used in this package's Update | ||||
| // operation. | ||||
| type UpdateOpts poolOpts | ||||
|  | ||||
| // ToPoolUpdateMap casts a UpdateOpts struct to a map. | ||||
| func (opts UpdateOpts) ToPoolUpdateMap() (map[string]interface{}, error) { | ||||
| 	l := make(map[string]interface{}) | ||||
| 	allowedLBMethod := map[LBMethod]bool{LBMethodRoundRobin: true, LBMethodLeastConnections: true, LBMethodSourceIp: true} | ||||
|  | ||||
| 	if opts.LBMethod != "" { | ||||
| 		if allowedLBMethod[opts.LBMethod] { | ||||
| 			l["lb_algorithm"] = opts.LBMethod | ||||
| 		} else { | ||||
| 			return nil, errValidLBMethodRequired | ||||
| 		} | ||||
| 	} | ||||
| 	if opts.Name != "" { | ||||
| 		l["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.Description != "" { | ||||
| 		l["description"] = opts.Description | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		l["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"pool": l}, nil | ||||
| } | ||||
|  | ||||
| // Update allows pools to be updated. | ||||
| func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { | ||||
| 	var res UpdateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToPoolUpdateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	// Send request to API | ||||
| 	_, res.Err = c.Put(resourceURL(c, id), reqBody, &res.Body, &gophercloud.RequestOpts{ | ||||
| 		OkCodes: []int{200}, | ||||
| 	}) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // Delete will permanently delete a particular pool based on its unique ID. | ||||
| func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { | ||||
| 	var res DeleteResult | ||||
| 	_, res.Err = c.Delete(resourceURL(c, id), nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // CreateOpts contains all the values needed to create a new Member for a Pool. | ||||
| type memberOpts struct { | ||||
| 	// Optional. Name of the Member. | ||||
| 	Name string | ||||
|  | ||||
| 	// Only required if the caller has an admin role and wants to create a Member | ||||
| 	// for another tenant. | ||||
| 	TenantID string | ||||
|  | ||||
| 	// Required. The IP address of the member to receive traffic from the load balancer. | ||||
| 	Address string | ||||
|  | ||||
| 	// Required. The port on which to listen for client traffic. | ||||
| 	ProtocolPort int | ||||
|  | ||||
| 	// 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. | ||||
| 	Weight int | ||||
|  | ||||
| 	// Optional.  If you omit this parameter, LBaaS uses the vip_subnet_id | ||||
| 	// parameter value for the subnet UUID. | ||||
| 	SubnetID string | ||||
|  | ||||
| 	// Optional. The administrative state of the Pool. A valid value is true (UP) | ||||
| 	// or false (DOWN). | ||||
| 	AdminStateUp *bool | ||||
| } | ||||
|  | ||||
| // MemberListOptsBuilder allows extensions to add additional parameters to the | ||||
| // Member List request. | ||||
| type MemberListOptsBuilder interface { | ||||
| 	ToMemberListQuery() (string, error) | ||||
| } | ||||
|  | ||||
| // MemberListOpts 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 MemberListOpts struct { | ||||
| 	Name         string `q:"name"` | ||||
| 	Weight       int    `q:"weight"` | ||||
| 	AdminStateUp *bool  `q:"admin_state_up"` | ||||
| 	TenantID     string `q:"tenant_id"` | ||||
| 	Address      string `q:"address"` | ||||
| 	ProtocolPort int    `q:"protocol_port"` | ||||
| 	ID           string `q:"id"` | ||||
| 	Limit        int    `q:"limit"` | ||||
| 	Marker       string `q:"marker"` | ||||
| 	SortKey      string `q:"sort_key"` | ||||
| 	SortDir      string `q:"sort_dir"` | ||||
| } | ||||
|  | ||||
| // ToMemberListQuery formats a ListOpts into a query string. | ||||
| func (opts MemberListOpts) ToMemberListQuery() (string, error) { | ||||
| 	q, err := gophercloud.BuildQueryString(opts) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return q.String(), nil | ||||
| } | ||||
|  | ||||
| // List returns a Pager which allows you to iterate over a collection of | ||||
| // 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 members that are owned by the | ||||
| // tenant who submits the request, unless an admin user submits the request. | ||||
| func ListAssociateMembers(c *gophercloud.ServiceClient, poolID string, opts MemberListOptsBuilder) pagination.Pager { | ||||
| 	url := memberRootURL(c, poolID) | ||||
| 	if opts != nil { | ||||
| 		query, err := opts.ToMemberListQuery() | ||||
| 		if err != nil { | ||||
| 			return pagination.Pager{Err: err} | ||||
| 		} | ||||
| 		url += query | ||||
| 	} | ||||
|  | ||||
| 	return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { | ||||
| 		return MemberPage{pagination.LinkedPageBase{PageResult: r}} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	errPoolIdRequired       = fmt.Errorf("PoolID is required") | ||||
| 	errAddressRequired      = fmt.Errorf("Address is required") | ||||
| 	errProtocolPortRequired = fmt.Errorf("ProtocolPort is required") | ||||
| ) | ||||
|  | ||||
| // MemberCreateOptsBuilder 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. | ||||
| type MemberCreateOptsBuilder interface { | ||||
| 	ToMemberCreateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // MemberCreateOpts is the common options struct used in this package's Create | ||||
| // operation. | ||||
| type MemberCreateOpts memberOpts | ||||
|  | ||||
| // ToMemberCreateMap casts a CreateOpts struct to a map. | ||||
| func (opts MemberCreateOpts) ToMemberCreateMap() (map[string]interface{}, error) { | ||||
| 	l := make(map[string]interface{}) | ||||
|  | ||||
| 	if opts.Address != "" { | ||||
| 		l["address"] = opts.Address | ||||
| 	} else { | ||||
| 		return nil, errAddressRequired | ||||
| 	} | ||||
| 	if opts.ProtocolPort != 0 { | ||||
| 		l["protocol_port"] = opts.ProtocolPort | ||||
| 	} else { | ||||
| 		return nil, errProtocolPortRequired | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		l["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
| 	if opts.Name != "" { | ||||
| 		l["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.TenantID != "" { | ||||
| 		l["tenant_id"] = opts.TenantID | ||||
| 	} | ||||
| 	if opts.SubnetID != "" { | ||||
| 		l["subnet_id"] = opts.SubnetID | ||||
| 	} | ||||
| 	if opts.Weight != 0 { | ||||
| 		l["weight"] = opts.Weight | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"member": l}, nil | ||||
| } | ||||
|  | ||||
| // CreateAssociateMember will create and associate a Member with a particular Pool. | ||||
| func CreateAssociateMember(c *gophercloud.ServiceClient, poolID string, opts MemberCreateOpts) AssociateResult { | ||||
| 	var res AssociateResult | ||||
|  | ||||
| 	if poolID == "" { | ||||
| 		res.Err = errPoolIdRequired | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	reqBody, err := opts.ToMemberCreateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	_, res.Err = c.Post(memberRootURL(c, poolID), reqBody, &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // Get retrieves a particular Pool Member based on its unique ID. | ||||
| func GetAssociateMember(c *gophercloud.ServiceClient, poolID string, memberID string) GetResult { | ||||
| 	var res GetResult | ||||
| 	_, res.Err = c.Get(memberResourceURL(c, poolID, memberID), &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // 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. | ||||
| type MemberUpdateOptsBuilder interface { | ||||
| 	ToMemberUpdateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // UpdateOpts is the common options struct used in this package's Update | ||||
| // operation. | ||||
| type MemberUpdateOpts memberOpts | ||||
|  | ||||
| // ToMemberUpdateMap casts a UpdateOpts struct to a map. | ||||
| func (opts MemberUpdateOpts) ToMemberUpdateMap() (map[string]interface{}, error) { | ||||
| 	l := make(map[string]interface{}) | ||||
|  | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		l["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
| 	if opts.Name != "" { | ||||
| 		l["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.Weight != 0 { | ||||
| 		l["weight"] = opts.Weight | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"member": l}, nil | ||||
| } | ||||
|  | ||||
| // Update allows Member to be updated. | ||||
| func UpdateAssociateMember(c *gophercloud.ServiceClient, poolID string, memberID string, opts MemberUpdateOpts) UpdateResult { | ||||
| 	var res UpdateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToMemberUpdateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	// Send request to API | ||||
| 	_, res.Err = c.Put(memberResourceURL(c, poolID, memberID), reqBody, &res.Body, &gophercloud.RequestOpts{ | ||||
| 		OkCodes: []int{200, 201, 202}, | ||||
| 	}) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // DisassociateMember will remove and disassociate a Member from a particular Pool. | ||||
| func DeleteMember(c *gophercloud.ServiceClient, poolID string, memberID string) DeleteResult { | ||||
| 	var res DeleteResult | ||||
| 	_, res.Err = c.Delete(memberResourceURL(c, poolID, memberID), nil) | ||||
| 	return res | ||||
| } | ||||
							
								
								
									
										274
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/results.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/results.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,274 @@ | ||||
| package pools | ||||
|  | ||||
| import ( | ||||
| 	"github.com/mitchellh/mapstructure" | ||||
| 	"github.com/rackspace/gophercloud" | ||||
| 	"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/monitors" | ||||
| 	"github.com/rackspace/gophercloud/pagination" | ||||
| ) | ||||
|  | ||||
| // SessionPersistence represents the session persistence feature of the load | ||||
| // balancing service. It attempts to force connections or requests in the same | ||||
| // session to be processed by the same member as long as it is ative. Three | ||||
| // types of persistence are supported: | ||||
| // | ||||
| // SOURCE_IP:   With this mode, all connections originating from the same source | ||||
| //              IP address, will be handled by the same Member of the Pool. | ||||
| // HTTP_COOKIE: With this persistence mode, the load balancing function will | ||||
| //              create a cookie on the first request from a client. Subsequent | ||||
| //              requests containing the same cookie value will be handled by | ||||
| //              the same Member of the Pool. | ||||
| // APP_COOKIE:  With this persistence mode, the load balancing function will | ||||
| //              rely on a cookie established by the backend application. All | ||||
| //              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 string `mapstructure:"type" json:"type"` | ||||
|  | ||||
| 	// Name of cookie if persistence mode is set appropriately | ||||
| 	CookieName string `mapstructure:"cookie_name" json:"cookie_name,omitempty"` | ||||
| } | ||||
|  | ||||
| type LoadBalancerID struct { | ||||
| 	ID string `mapstructure:"id" json:"id"` | ||||
| } | ||||
|  | ||||
| type ListenerID struct { | ||||
| 	ID string `mapstructure:"id" json:"id"` | ||||
| } | ||||
|  | ||||
| // Pool represents a logical set of devices, such as web servers, that you | ||||
| // group together to receive and process traffic. The load balancing function | ||||
| // chooses a Member of the Pool according to the configured load balancing | ||||
| // method to handle the new requests or connections received on the VIP address. | ||||
| type Pool struct { | ||||
| 	// 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 string `json:"lb_algorithm" mapstructure:"lb_algorithm"` | ||||
|  | ||||
| 	// The protocol of the Pool, which is TCP, HTTP, or HTTPS. | ||||
| 	Protocol string | ||||
|  | ||||
| 	// Description for the Pool. | ||||
| 	Description string | ||||
|  | ||||
| 	// A list of listeners objects IDs. | ||||
| 	Listeners []ListenerID `mapstructure:"listeners" json:"listeners"` //[]map[string]interface{} | ||||
|  | ||||
| 	// A list of member objects IDs. | ||||
| 	Members []Member `mapstructure:"members" json:"members"` | ||||
|  | ||||
| 	// The ID of associated health monitor. | ||||
| 	MonitorID string `json:"healthmonitor_id" mapstructure:"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" mapstructure:"subnet_id"` | ||||
|  | ||||
| 	// Owner of the Pool. Only an administrative user can specify a tenant ID | ||||
| 	// other than its own. | ||||
| 	TenantID string `json:"tenant_id" mapstructure:"tenant_id"` | ||||
|  | ||||
| 	// The administrative state of the Pool, which is up (true) or down (false). | ||||
| 	AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"` | ||||
|  | ||||
| 	// Pool name. Does not have to be unique. | ||||
| 	Name string | ||||
|  | ||||
| 	// The unique ID for the Pool. | ||||
| 	ID string | ||||
|  | ||||
| 	// A list of load balancer objects IDs. | ||||
| 	Loadbalancers []LoadBalancerID `mapstructure:"loadbalancers" json:"loadbalancers"` | ||||
|  | ||||
| 	// Indicates whether connections in the same session will be processed by the | ||||
| 	// same Pool member or not. | ||||
| 	Persistence SessionPersistence `mapstructure:"session_persistence" json:"session_persistence"` | ||||
|  | ||||
| 	// The provider | ||||
| 	Provider string | ||||
|  | ||||
| 	Monitor monitors.Monitor `mapstructure:"healthmonitor" json:"healthmonitor"` | ||||
| } | ||||
|  | ||||
| // PoolPage is the page returned by a pager when traversing over a | ||||
| // collection of pools. | ||||
| type PoolPage struct { | ||||
| 	pagination.LinkedPageBase | ||||
| } | ||||
|  | ||||
| // NextPageURL is invoked when a paginated collection of pools 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 (p PoolPage) NextPageURL() (string, error) { | ||||
| 	type resp struct { | ||||
| 		Links []gophercloud.Link `mapstructure:"pools_links"` | ||||
| 	} | ||||
|  | ||||
| 	var r resp | ||||
| 	err := mapstructure.Decode(p.Body, &r) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return gophercloud.ExtractNextURL(r.Links) | ||||
| } | ||||
|  | ||||
| // IsEmpty checks whether a PoolPage struct is empty. | ||||
| func (p PoolPage) IsEmpty() (bool, error) { | ||||
| 	is, err := ExtractPools(p) | ||||
| 	if err != nil { | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return len(is) == 0, nil | ||||
| } | ||||
|  | ||||
| // ExtractPools accepts a Page struct, specifically a RouterPage 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(page pagination.Page) ([]Pool, error) { | ||||
| 	var resp struct { | ||||
| 		Pools []Pool `mapstructure:"pools" json:"pools"` | ||||
| 	} | ||||
|  | ||||
| 	err := mapstructure.Decode(page.(PoolPage).Body, &resp) | ||||
|  | ||||
| 	return resp.Pools, err | ||||
| } | ||||
|  | ||||
| type commonResult struct { | ||||
| 	gophercloud.Result | ||||
| } | ||||
|  | ||||
| // Extract is a function that accepts a result and extracts a router. | ||||
| func (r commonResult) Extract() (*Pool, error) { | ||||
| 	if r.Err != nil { | ||||
| 		return nil, r.Err | ||||
| 	} | ||||
|  | ||||
| 	var res struct { | ||||
| 		Pool *Pool `json:"pool"` | ||||
| 	} | ||||
|  | ||||
| 	err := mapstructure.Decode(r.Body, &res) | ||||
|  | ||||
| 	return res.Pool, err | ||||
| } | ||||
|  | ||||
| // Member represents the application running on a backend server. | ||||
| type Member struct { | ||||
| 	// Name of the Member. | ||||
| 	Name string `json:"name" mapstructure:"name"` | ||||
|  | ||||
| 	// Weight of Member. | ||||
| 	Weight int `json:"weight" mapstructure:"weight"` | ||||
|  | ||||
| 	// The administrative state of the member, which is up (true) or down (false). | ||||
| 	AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"` | ||||
|  | ||||
| 	// Owner of the Member. Only an administrative user can specify a tenant ID | ||||
| 	// other than its own. | ||||
| 	TenantID string `json:"tenant_id" mapstructure:"tenant_id"` | ||||
|  | ||||
| 	// parameter value for the subnet UUID. | ||||
| 	SubnetID string `json:"subnet_id" mapstructure:"subnet_id"` | ||||
|  | ||||
| 	// The Pool to which the Member belongs. | ||||
| 	PoolID string `json:"pool_id" mapstructure:"pool_id"` | ||||
|  | ||||
| 	// The IP address of the Member. | ||||
| 	Address string `json:"address" mapstructure:"address"` | ||||
|  | ||||
| 	// The port on which the application is hosted. | ||||
| 	ProtocolPort int `json:"protocol_port" mapstructure:"protocol_port"` | ||||
|  | ||||
| 	// The unique ID for the Member. | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // MemberPage is the page returned by a pager when traversing over a | ||||
| // collection of Members in a Pool. | ||||
| type MemberPage struct { | ||||
| 	pagination.LinkedPageBase | ||||
| } | ||||
|  | ||||
| // NextPageURL is invoked when a paginated collection of members 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 (p MemberPage) NextPageURL() (string, error) { | ||||
| 	type resp struct { | ||||
| 		Links []gophercloud.Link `mapstructure:"members_links"` | ||||
| 	} | ||||
|  | ||||
| 	var r resp | ||||
| 	err := mapstructure.Decode(p.Body, &r) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return gophercloud.ExtractNextURL(r.Links) | ||||
| } | ||||
|  | ||||
| // IsEmpty checks whether a MemberPage struct is empty. | ||||
| func (p MemberPage) IsEmpty() (bool, error) { | ||||
| 	is, err := ExtractMembers(p) | ||||
| 	if err != nil { | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return len(is) == 0, nil | ||||
| } | ||||
|  | ||||
| // ExtractMembers accepts a Page struct, specifically a RouterPage struct, | ||||
| // and extracts the elements into a slice of Router structs. In other words, | ||||
| // a generic collection is mapped into a relevant slice. | ||||
| func ExtractMembers(page pagination.Page) ([]Member, error) { | ||||
| 	var resp struct { | ||||
| 		Member []Member `mapstructure:"members" json:"members"` | ||||
| 	} | ||||
|  | ||||
| 	err := mapstructure.Decode(page.(MemberPage).Body, &resp) | ||||
|  | ||||
| 	return resp.Member, err | ||||
| } | ||||
|  | ||||
| // ExtractMember is a function that accepts a result and extracts a router. | ||||
| func (r commonResult) ExtractMember() (*Member, error) { | ||||
| 	if r.Err != nil { | ||||
| 		return nil, r.Err | ||||
| 	} | ||||
|  | ||||
| 	var res struct { | ||||
| 		Member *Member `json:"member"` | ||||
| 	} | ||||
|  | ||||
| 	err := mapstructure.Decode(r.Body, &res) | ||||
|  | ||||
| 	return res.Member, err | ||||
| } | ||||
|  | ||||
| // CreateResult represents the result of a create operation. | ||||
| type CreateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // GetResult represents the result of a get operation. | ||||
| type GetResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // UpdateResult represents the result of an update operation. | ||||
| type UpdateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // DeleteResult represents the result of a delete operation. | ||||
| type DeleteResult struct { | ||||
| 	gophercloud.ErrResult | ||||
| } | ||||
|  | ||||
| // AssociateResult represents the result of an association operation. | ||||
| type AssociateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
							
								
								
									
										25
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/urls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/extensions/lbaas_v2/pools/urls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| package pools | ||||
|  | ||||
| import "github.com/rackspace/gophercloud" | ||||
|  | ||||
| const ( | ||||
| 	rootPath     = "lbaas" | ||||
| 	resourcePath = "pools" | ||||
| 	memberPath   = "members" | ||||
| ) | ||||
|  | ||||
| func rootURL(c *gophercloud.ServiceClient) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath) | ||||
| } | ||||
|  | ||||
| func resourceURL(c *gophercloud.ServiceClient, id string) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath, id) | ||||
| } | ||||
|  | ||||
| func memberRootURL(c *gophercloud.ServiceClient, poolId string) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath, poolId, memberPath) | ||||
| } | ||||
|  | ||||
| func memberResourceURL(c *gophercloud.ServiceClient, poolID string, memeberID string) string { | ||||
| 	return c.ServiceURL(rootPath, resourcePath, poolID, memberPath, memeberID) | ||||
| } | ||||
							
								
								
									
										8
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| // 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 | ||||
							
								
								
									
										11
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/errors.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/errors.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| package ports | ||||
|  | ||||
| import "fmt" | ||||
|  | ||||
| func err(str string) error { | ||||
| 	return fmt.Errorf("%s", str) | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	errNetworkIDRequired = err("A Network ID is required") | ||||
| ) | ||||
							
								
								
									
										268
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										268
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/requests.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,268 @@ | ||||
| package ports | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/rackspace/gophercloud" | ||||
| 	"github.com/rackspace/gophercloud/pagination" | ||||
| ) | ||||
|  | ||||
| // AdminState gives users a solid type to work with for create and update | ||||
| // operations. It is recommended that users use the `Up` and `Down` enums. | ||||
| type AdminState *bool | ||||
|  | ||||
| // Convenience vars for AdminStateUp values. | ||||
| var ( | ||||
| 	iTrue  = true | ||||
| 	iFalse = false | ||||
|  | ||||
| 	Up   AdminState = &iTrue | ||||
| 	Down AdminState = &iFalse | ||||
| ) | ||||
|  | ||||
| // ListOptsBuilder allows extensions to add additional parameters to the | ||||
| // List request. | ||||
| type ListOptsBuilder interface { | ||||
| 	ToPortListQuery() (string, error) | ||||
| } | ||||
|  | ||||
| // 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 port attributes you want to see returned. SortKey allows you to sort | ||||
| // by a particular port attribute. SortDir sets the direction, and is either | ||||
| // `asc' or `desc'. Marker and Limit are used for pagination. | ||||
| type ListOpts struct { | ||||
| 	Status       string `q:"status"` | ||||
| 	Name         string `q:"name"` | ||||
| 	AdminStateUp *bool  `q:"admin_state_up"` | ||||
| 	NetworkID    string `q:"network_id"` | ||||
| 	TenantID     string `q:"tenant_id"` | ||||
| 	DeviceOwner  string `q:"device_owner"` | ||||
| 	MACAddress   string `q:"mac_address"` | ||||
| 	ID           string `q:"id"` | ||||
| 	DeviceID     string `q:"device_id"` | ||||
| 	Limit        int    `q:"limit"` | ||||
| 	Marker       string `q:"marker"` | ||||
| 	SortKey      string `q:"sort_key"` | ||||
| 	SortDir      string `q:"sort_dir"` | ||||
| } | ||||
|  | ||||
| // ToPortListQuery formats a ListOpts into a query string. | ||||
| func (opts ListOpts) ToPortListQuery() (string, error) { | ||||
| 	q, err := gophercloud.BuildQueryString(opts) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return q.String(), nil | ||||
| } | ||||
|  | ||||
| // List returns a Pager which allows you to iterate over a collection of | ||||
| // ports. It accepts a ListOpts struct, which allows you to filter and sort | ||||
| // the returned collection for greater efficiency. | ||||
| // | ||||
| // Default policy settings return only those ports that are owned by the tenant | ||||
| // who submits the request, unless the request is submitted by a user with | ||||
| // administrative rights. | ||||
| func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { | ||||
| 	url := listURL(c) | ||||
| 	if opts != nil { | ||||
| 		query, err := opts.ToPortListQuery() | ||||
| 		if err != nil { | ||||
| 			return pagination.Pager{Err: err} | ||||
| 		} | ||||
| 		url += query | ||||
| 	} | ||||
|  | ||||
| 	return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { | ||||
| 		return PortPage{pagination.LinkedPageBase{PageResult: r}} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // Get retrieves a specific port based on its unique ID. | ||||
| func Get(c *gophercloud.ServiceClient, id string) GetResult { | ||||
| 	var res GetResult | ||||
| 	_, res.Err = c.Get(getURL(c, id), &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // 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. | ||||
| type CreateOptsBuilder interface { | ||||
| 	ToPortCreateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // CreateOpts represents the attributes used when creating a new port. | ||||
| type CreateOpts struct { | ||||
| 	NetworkID           string | ||||
| 	Name                string | ||||
| 	AdminStateUp        *bool | ||||
| 	MACAddress          string | ||||
| 	FixedIPs            interface{} | ||||
| 	DeviceID            string | ||||
| 	DeviceOwner         string | ||||
| 	TenantID            string | ||||
| 	SecurityGroups      []string | ||||
| 	AllowedAddressPairs []AddressPair | ||||
| } | ||||
|  | ||||
| // ToPortCreateMap casts a CreateOpts struct to a map. | ||||
| func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) { | ||||
| 	p := make(map[string]interface{}) | ||||
|  | ||||
| 	if opts.NetworkID == "" { | ||||
| 		return nil, errNetworkIDRequired | ||||
| 	} | ||||
| 	p["network_id"] = opts.NetworkID | ||||
|  | ||||
| 	if opts.DeviceID != "" { | ||||
| 		p["device_id"] = opts.DeviceID | ||||
| 	} | ||||
| 	if opts.DeviceOwner != "" { | ||||
| 		p["device_owner"] = opts.DeviceOwner | ||||
| 	} | ||||
| 	if opts.FixedIPs != nil { | ||||
| 		p["fixed_ips"] = opts.FixedIPs | ||||
| 	} | ||||
| 	if opts.SecurityGroups != nil { | ||||
| 		p["security_groups"] = opts.SecurityGroups | ||||
| 	} | ||||
| 	if opts.TenantID != "" { | ||||
| 		p["tenant_id"] = opts.TenantID | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		p["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
| 	if opts.Name != "" { | ||||
| 		p["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.MACAddress != "" { | ||||
| 		p["mac_address"] = opts.MACAddress | ||||
| 	} | ||||
| 	if opts.AllowedAddressPairs != nil { | ||||
| 		p["allowed_address_pairs"] = opts.AllowedAddressPairs | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"port": p}, nil | ||||
| } | ||||
|  | ||||
| // Create accepts a CreateOpts struct and creates a new network using the values | ||||
| // provided. You must remember to provide a NetworkID value. | ||||
| func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { | ||||
| 	var res CreateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToPortCreateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	_, res.Err = c.Post(createURL(c), reqBody, &res.Body, nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // 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. | ||||
| type UpdateOptsBuilder interface { | ||||
| 	ToPortUpdateMap() (map[string]interface{}, error) | ||||
| } | ||||
|  | ||||
| // UpdateOpts represents the attributes used when updating an existing port. | ||||
| type UpdateOpts struct { | ||||
| 	Name                string | ||||
| 	AdminStateUp        *bool | ||||
| 	FixedIPs            interface{} | ||||
| 	DeviceID            string | ||||
| 	DeviceOwner         string | ||||
| 	SecurityGroups      []string | ||||
| 	AllowedAddressPairs []AddressPair | ||||
| } | ||||
|  | ||||
| // ToPortUpdateMap casts an UpdateOpts struct to a map. | ||||
| func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) { | ||||
| 	p := make(map[string]interface{}) | ||||
|  | ||||
| 	if opts.DeviceID != "" { | ||||
| 		p["device_id"] = opts.DeviceID | ||||
| 	} | ||||
| 	if opts.DeviceOwner != "" { | ||||
| 		p["device_owner"] = opts.DeviceOwner | ||||
| 	} | ||||
| 	if opts.FixedIPs != nil { | ||||
| 		p["fixed_ips"] = opts.FixedIPs | ||||
| 	} | ||||
| 	if opts.SecurityGroups != nil { | ||||
| 		p["security_groups"] = opts.SecurityGroups | ||||
| 	} | ||||
| 	if opts.AdminStateUp != nil { | ||||
| 		p["admin_state_up"] = &opts.AdminStateUp | ||||
| 	} | ||||
| 	if opts.Name != "" { | ||||
| 		p["name"] = opts.Name | ||||
| 	} | ||||
| 	if opts.AllowedAddressPairs != nil { | ||||
| 		p["allowed_address_pairs"] = opts.AllowedAddressPairs | ||||
| 	} | ||||
|  | ||||
| 	return map[string]interface{}{"port": p}, nil | ||||
| } | ||||
|  | ||||
| // Update accepts a UpdateOpts struct and updates an existing port using the | ||||
| // values provided. | ||||
| func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { | ||||
| 	var res UpdateResult | ||||
|  | ||||
| 	reqBody, err := opts.ToPortUpdateMap() | ||||
| 	if err != nil { | ||||
| 		res.Err = err | ||||
| 		return res | ||||
| 	} | ||||
|  | ||||
| 	_, res.Err = c.Put(updateURL(c, id), reqBody, &res.Body, &gophercloud.RequestOpts{ | ||||
| 		OkCodes: []int{200, 201}, | ||||
| 	}) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // Delete accepts a unique ID and deletes the port associated with it. | ||||
| func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { | ||||
| 	var res DeleteResult | ||||
| 	_, res.Err = c.Delete(deleteURL(c, id), nil) | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| // IDFromName is a convenience function that returns a port's ID given its name. | ||||
| func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { | ||||
| 	portCount := 0 | ||||
| 	portID := "" | ||||
| 	if name == "" { | ||||
| 		return "", fmt.Errorf("A port name must be provided.") | ||||
| 	} | ||||
| 	pager := List(client, nil) | ||||
| 	pager.EachPage(func(page pagination.Page) (bool, error) { | ||||
| 		portList, err := ExtractPorts(page) | ||||
| 		if err != nil { | ||||
| 			return false, err | ||||
| 		} | ||||
|  | ||||
| 		for _, p := range portList { | ||||
| 			if p.Name == name { | ||||
| 				portCount++ | ||||
| 				portID = p.ID | ||||
| 			} | ||||
| 		} | ||||
| 		return true, nil | ||||
| 	}) | ||||
|  | ||||
| 	switch portCount { | ||||
| 	case 0: | ||||
| 		return "", fmt.Errorf("Unable to find port: %s", name) | ||||
| 	case 1: | ||||
| 		return portID, nil | ||||
| 	default: | ||||
| 		return "", fmt.Errorf("Found %d ports matching %s", portCount, name) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										132
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/results.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/results.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| package ports | ||||
|  | ||||
| import ( | ||||
| 	"github.com/mitchellh/mapstructure" | ||||
| 	"github.com/rackspace/gophercloud" | ||||
| 	"github.com/rackspace/gophercloud/pagination" | ||||
| ) | ||||
|  | ||||
| type commonResult struct { | ||||
| 	gophercloud.Result | ||||
| } | ||||
|  | ||||
| // Extract is a function that accepts a result and extracts a port resource. | ||||
| func (r commonResult) Extract() (*Port, error) { | ||||
| 	if r.Err != nil { | ||||
| 		return nil, r.Err | ||||
| 	} | ||||
|  | ||||
| 	var res struct { | ||||
| 		Port *Port `json:"port"` | ||||
| 	} | ||||
| 	err := mapstructure.Decode(r.Body, &res) | ||||
|  | ||||
| 	return res.Port, err | ||||
| } | ||||
|  | ||||
| // CreateResult represents the result of a create operation. | ||||
| type CreateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // GetResult represents the result of a get operation. | ||||
| type GetResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // UpdateResult represents the result of an update operation. | ||||
| type UpdateResult struct { | ||||
| 	commonResult | ||||
| } | ||||
|  | ||||
| // DeleteResult represents the result of a delete operation. | ||||
| type DeleteResult struct { | ||||
| 	gophercloud.ErrResult | ||||
| } | ||||
|  | ||||
| // IP is a sub-struct that represents an individual IP. | ||||
| type IP struct { | ||||
| 	SubnetID  string `mapstructure:"subnet_id" json:"subnet_id"` | ||||
| 	IPAddress string `mapstructure:"ip_address" json:"ip_address,omitempty"` | ||||
| } | ||||
|  | ||||
| type AddressPair struct { | ||||
| 	IPAddress  string `mapstructure:"ip_address" json:"ip_address,omitempty"` | ||||
| 	MACAddress string `mapstructure:"mac_address" json:"mac_address,omitempty"` | ||||
| } | ||||
|  | ||||
| // Port represents a Neutron port. See package documentation for a top-level | ||||
| // description of what this is. | ||||
| type Port struct { | ||||
| 	// UUID for the port. | ||||
| 	ID string `mapstructure:"id" json:"id"` | ||||
| 	// Network that this port is associated with. | ||||
| 	NetworkID string `mapstructure:"network_id" json:"network_id"` | ||||
| 	// Human-readable name for the port. Might not be unique. | ||||
| 	Name string `mapstructure:"name" json:"name"` | ||||
| 	// Administrative state of port. If false (down), port does not forward packets. | ||||
| 	AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"` | ||||
| 	// Indicates whether network is currently operational. Possible values include | ||||
| 	// `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional values. | ||||
| 	Status string `mapstructure:"status" json:"status"` | ||||
| 	// Mac address to use on this port. | ||||
| 	MACAddress string `mapstructure:"mac_address" 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 `mapstructure:"fixed_ips" json:"fixed_ips"` | ||||
| 	// Owner of network. Only admin users can specify a tenant_id other than its own. | ||||
| 	TenantID string `mapstructure:"tenant_id" json:"tenant_id"` | ||||
| 	// Identifies the entity (e.g.: dhcp agent) using this port. | ||||
| 	DeviceOwner string `mapstructure:"device_owner" json:"device_owner"` | ||||
| 	// Specifies the IDs of any security groups associated with a port. | ||||
| 	SecurityGroups []string `mapstructure:"security_groups" json:"security_groups"` | ||||
| 	// Identifies the device (e.g., virtual server) using this port. | ||||
| 	DeviceID string `mapstructure:"device_id" json:"device_id"` | ||||
| 	// Identifies the list of IP addresses the port will recognize/accept | ||||
| 	AllowedAddressPairs []AddressPair `mapstructure:"allowed_address_pairs" json:"allowed_address_pairs"` | ||||
| } | ||||
|  | ||||
| // PortPage is the page returned by a pager when traversing over a collection | ||||
| // of network ports. | ||||
| type PortPage struct { | ||||
| 	pagination.LinkedPageBase | ||||
| } | ||||
|  | ||||
| // NextPageURL is invoked when a paginated collection of ports 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 (p PortPage) NextPageURL() (string, error) { | ||||
| 	type resp struct { | ||||
| 		Links []gophercloud.Link `mapstructure:"ports_links"` | ||||
| 	} | ||||
|  | ||||
| 	var r resp | ||||
| 	err := mapstructure.Decode(p.Body, &r) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	return gophercloud.ExtractNextURL(r.Links) | ||||
| } | ||||
|  | ||||
| // IsEmpty checks whether a PortPage struct is empty. | ||||
| func (p PortPage) IsEmpty() (bool, error) { | ||||
| 	is, err := ExtractPorts(p) | ||||
| 	if err != nil { | ||||
| 		return true, nil | ||||
| 	} | ||||
| 	return len(is) == 0, nil | ||||
| } | ||||
|  | ||||
| // ExtractPorts accepts a Page struct, specifically a PortPage struct, | ||||
| // and extracts the elements into a slice of Port structs. In other words, | ||||
| // a generic collection is mapped into a relevant slice. | ||||
| func ExtractPorts(page pagination.Page) ([]Port, error) { | ||||
| 	var resp struct { | ||||
| 		Ports []Port `mapstructure:"ports" json:"ports"` | ||||
| 	} | ||||
|  | ||||
| 	err := mapstructure.Decode(page.(PortPage).Body, &resp) | ||||
|  | ||||
| 	return resp.Ports, err | ||||
| } | ||||
							
								
								
									
										31
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/urls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/rackspace/gophercloud/openstack/networking/v2/ports/urls.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| package ports | ||||
|  | ||||
| import "github.com/rackspace/gophercloud" | ||||
|  | ||||
| func resourceURL(c *gophercloud.ServiceClient, id string) string { | ||||
| 	return c.ServiceURL("ports", id) | ||||
| } | ||||
|  | ||||
| func rootURL(c *gophercloud.ServiceClient) string { | ||||
| 	return c.ServiceURL("ports") | ||||
| } | ||||
|  | ||||
| func listURL(c *gophercloud.ServiceClient) string { | ||||
| 	return rootURL(c) | ||||
| } | ||||
|  | ||||
| func getURL(c *gophercloud.ServiceClient, id string) string { | ||||
| 	return resourceURL(c, id) | ||||
| } | ||||
|  | ||||
| func createURL(c *gophercloud.ServiceClient) string { | ||||
| 	return rootURL(c) | ||||
| } | ||||
|  | ||||
| func updateURL(c *gophercloud.ServiceClient, id string) string { | ||||
| 	return resourceURL(c, id) | ||||
| } | ||||
|  | ||||
| func deleteURL(c *gophercloud.ServiceClient, id string) string { | ||||
| 	return resourceURL(c, id) | ||||
| } | ||||
							
								
								
									
										14
									
								
								vendor/github.com/rackspace/gophercloud/pagination/pager.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/rackspace/gophercloud/pagination/pager.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -138,6 +138,11 @@ func (p Pager) AllPages() (Page, error) { | ||||
| 	// that type. | ||||
| 	pageType := reflect.TypeOf(testPage) | ||||
|  | ||||
| 	// if it's a single page, just return the testPage (first page) | ||||
| 	if _, found := pageType.FieldByName("SinglePageBase"); found { | ||||
| 		return testPage, nil | ||||
| 	} | ||||
|  | ||||
| 	// Switch on the page body type. Recognized types are `map[string]interface{}`, | ||||
| 	// `[]byte`, and `[]interface{}`. | ||||
| 	switch testPage.GetBody().(type) { | ||||
| @@ -153,7 +158,14 @@ func (p Pager) AllPages() (Page, error) { | ||||
| 					key = k | ||||
| 				} | ||||
| 			} | ||||
| 			pagesSlice = append(pagesSlice, b[key].([]interface{})...) | ||||
| 			switch keyType := b[key].(type) { | ||||
| 			case map[string]interface{}: | ||||
| 				pagesSlice = append(pagesSlice, keyType) | ||||
| 			case []interface{}: | ||||
| 				pagesSlice = append(pagesSlice, b[key].([]interface{})...) | ||||
| 			default: | ||||
| 				return false, fmt.Errorf("Unsupported page body type: %+v", keyType) | ||||
| 			} | ||||
| 			return true, nil | ||||
| 		}) | ||||
| 		if err != nil { | ||||
|   | ||||
							
								
								
									
										10
									
								
								vendor/github.com/rackspace/gophercloud/rackspace/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/rackspace/gophercloud/rackspace/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -222,3 +222,13 @@ func NewDBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (* | ||||
| 	} | ||||
| 	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil | ||||
| } | ||||
|  | ||||
| // NewAutoScaleV1 creates a ServiceClient that may be used to access the v1 Auto Scale service. | ||||
| func NewAutoScaleV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { | ||||
| 	eo.ApplyDefaults("rax:autoscale") | ||||
| 	url, err := client.EndpointLocator(eo) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user