1/*
2Package gophercloud provides a multi-vendor interface to OpenStack-compatible
3clouds. The library has a three-level hierarchy: providers, services, and
4resources.
5
6Authenticating with Providers
7
8Provider structs represent the cloud providers that offer and manage a
9collection of services. You will generally want to create one Provider
10client per OpenStack cloud.
11
12	It is now recommended to use the `clientconfig` package found at
13	https://github.com/gophercloud/utils/tree/master/openstack/clientconfig
14	for all authentication purposes.
15
16	The below documentation is still relevant. clientconfig simply implements
17	the below and presents it in an easier and more flexible way.
18
19Use your OpenStack credentials to create a Provider client.  The
20IdentityEndpoint is typically refered to as "auth_url" or "OS_AUTH_URL" in
21information provided by the cloud operator. Additionally, the cloud may refer to
22TenantID or TenantName as project_id and project_name. Credentials are
23specified like so:
24
25	opts := gophercloud.AuthOptions{
26		IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
27		Username: "{username}",
28		Password: "{password}",
29		TenantID: "{tenant_id}",
30	}
31
32	provider, err := openstack.AuthenticatedClient(opts)
33
34You can authenticate with a token by doing:
35
36	opts := gophercloud.AuthOptions{
37		IdentityEndpoint: "https://openstack.example.com:5000/v2.0",
38		TokenID:  "{token_id}",
39		TenantID: "{tenant_id}",
40	}
41
42	provider, err := openstack.AuthenticatedClient(opts)
43
44You may also use the openstack.AuthOptionsFromEnv() helper function. This
45function reads in standard environment variables frequently found in an
46OpenStack `openrc` file. Again note that Gophercloud currently uses "tenant"
47instead of "project".
48
49	opts, err := openstack.AuthOptionsFromEnv()
50	provider, err := openstack.AuthenticatedClient(opts)
51
52Service Clients
53
54Service structs are specific to a provider and handle all of the logic and
55operations for a particular OpenStack service. Examples of services include:
56Compute, Object Storage, Block Storage. In order to define one, you need to
57pass in the parent provider, like so:
58
59	opts := gophercloud.EndpointOpts{Region: "RegionOne"}
60
61	client, err := openstack.NewComputeV2(provider, opts)
62
63Resources
64
65Resource structs are the domain models that services make use of in order
66to work with and represent the state of API resources:
67
68	server, err := servers.Get(client, "{serverId}").Extract()
69
70Intermediate Result structs are returned for API operations, which allow
71generic access to the HTTP headers, response body, and any errors associated
72with the network transaction. To turn a result into a usable resource struct,
73you must call the Extract method which is chained to the response, or an
74Extract function from an applicable extension:
75
76	result := servers.Get(client, "{serverId}")
77
78	// Attempt to extract the disk configuration from the OS-DCF disk config
79	// extension:
80	config, err := diskconfig.ExtractGet(result)
81
82All requests that enumerate a collection return a Pager struct that is used to
83iterate through the results one page at a time. Use the EachPage method on that
84Pager to handle each successive Page in a closure, then use the appropriate
85extraction method from that request's package to interpret that Page as a slice
86of results:
87
88	err := servers.List(client, nil).EachPage(func (page pagination.Page) (bool, error) {
89		s, err := servers.ExtractServers(page)
90		if err != nil {
91			return false, err
92		}
93
94		// Handle the []servers.Server slice.
95
96		// Return "false" or an error to prematurely stop fetching new pages.
97		return true, nil
98	})
99
100If you want to obtain the entire collection of pages without doing any
101intermediary processing on each page, you can use the AllPages method:
102
103	allPages, err := servers.List(client, nil).AllPages()
104	allServers, err := servers.ExtractServers(allPages)
105
106This top-level package contains utility functions and data types that are used
107throughout the provider and service packages. Of particular note for end users
108are the AuthOptions and EndpointOpts structs.
109
110An example retry backoff function, which respects the 429 HTTP response code and a "Retry-After" header:
111
112	endpoint := "http://localhost:5000"
113	provider, err := openstack.NewClient(endpoint)
114	if err != nil {
115		panic(err)
116	}
117	provider.MaxBackoffRetries = 3 // max three retries
118	provider.RetryBackoffFunc = func(ctx context.Context, respErr *ErrUnexpectedResponseCode, e error, retries uint) error {
119		retryAfter := respErr.ResponseHeader.Get("Retry-After")
120		if retryAfter == "" {
121			return e
122		}
123
124		var sleep time.Duration
125
126		// Parse delay seconds or HTTP date
127		if v, err := strconv.ParseUint(retryAfter, 10, 32); err == nil {
128			sleep = time.Duration(v) * time.Second
129		} else if v, err := time.Parse(http.TimeFormat, retryAfter); err == nil {
130			sleep = time.Until(v)
131		} else {
132			return e
133		}
134
135		if ctx != nil {
136			select {
137			case <-time.After(sleep):
138			case <-ctx.Done():
139				return e
140			}
141		} else {
142			time.Sleep(sleep)
143		}
144
145		return nil
146	}
147
148*/
149package gophercloud
150