Docs revision for current status

* Update README to add a note about the reorg in progress
* Rename misc to uitl
* Add openstack directory

Change-Id: I3f318116b1406fa862715236cc9001dea0f9231c
This commit is contained in:
Dean Troyer 2015-04-17 19:44:27 -05:00
parent 03e6c8f314
commit 124ac5cc92
10 changed files with 62 additions and 49 deletions

View File

@ -1,5 +1,8 @@
Golang Client OpenStack Golang Client
============= =======================
NOTE(dtroyer) Apr 2015: This repo is under heavy revision as it is being revived.
stackforge/golang-client is yet another implementation of [OpenStack] stackforge/golang-client is yet another implementation of [OpenStack]
(http://www.openstack.org/) API client in [Go language](http://golang.org). (http://www.openstack.org/) API client in [Go language](http://golang.org).
The code follows OpenStack licensing and borrows its infrastructure for code The code follows OpenStack licensing and borrows its infrastructure for code
@ -17,7 +20,7 @@ Installation
Use `go get git.openstack.org/stackforge/golang-client.git`. Or alternatively, Use `go get git.openstack.org/stackforge/golang-client.git`. Or alternatively,
download or clone the repository. download or clone the repository.
The lib was developed and tested on go 1.2. No external dependencies, so far. The lib was developed and tested on go 1.3. No external dependencies, so far.
Examples Examples
-------- --------
@ -37,7 +40,7 @@ The tests were written against the [OpenStack API specifications]
(http://docs.openstack.org/api/api-specs.html). (http://docs.openstack.org/api/api-specs.html).
The integration test were successful against the following: The integration test were successful against the following:
- [HP Helion Public Cloud](http://docs.hpcloud.com/api/) - [DevStack](http://devstack.org)
If you use another provider and successfully completed the tests, please email If you use another provider and successfully completed the tests, please email
the maintainer(s) so your service can be mentioned here. Alternatively, if you the maintainer(s) so your service can be mentioned here. Alternatively, if you

View File

@ -20,10 +20,11 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"git.openstack.org/stackforge/golang-client.git/misc"
"io/ioutil" "io/ioutil"
"strings" "strings"
"time" "time"
"git.openstack.org/stackforge/golang-client.git/util"
) )
type Auth struct { type Auth struct {
@ -127,7 +128,7 @@ func AuthTenantNameTokenId(url, tenantName, tokenId string) (Auth, error) {
func auth(url, jsonStr *string) (Auth, error) { func auth(url, jsonStr *string) (Auth, error) {
var s []byte = []byte(*jsonStr) var s []byte = []byte(*jsonStr)
resp, err := misc.CallAPI("POST", *url, &s, resp, err := util.CallAPI("POST", *url, &s,
"Accept-Encoding", "gzip,deflate", "Accept-Encoding", "gzip,deflate",
"Accept", "application/json", "Accept", "application/json",
"Content-Type", "application/json", "Content-Type", "application/json",
@ -135,7 +136,7 @@ func auth(url, jsonStr *string) (Auth, error) {
if err != nil { if err != nil {
return Auth{}, err return Auth{}, err
} }
if err = misc.CheckHTTPResponseStatusCode(resp); err != nil { if err = util.CheckHTTPResponseStatusCode(resp); err != nil {
return Auth{}, err return Auth{}, err
} }
var contentType string = strings.ToLower(resp.Header.Get("Content-Type")) var contentType string = strings.ToLower(resp.Header.Get("Content-Type"))

View File

@ -24,9 +24,10 @@ package image
import ( import (
"fmt" "fmt"
"git.openstack.org/stackforge/golang-client.git/misc"
"net/http" "net/http"
"net/url" "net/url"
"git.openstack.org/stackforge/golang-client.git/util"
) )
// Service is a client service that can make // Service is a client service that can make
@ -56,9 +57,9 @@ type Response struct {
type DetailResponse struct { type DetailResponse struct {
CheckSum string `json:"checksum"` CheckSum string `json:"checksum"`
ContainerFormat string `json:"container_format"` ContainerFormat string `json:"container_format"`
CreatedAt misc.RFC8601DateTime `json:"created_at"` CreatedAt util.RFC8601DateTime `json:"created_at"`
Deleted bool `json:"deleted"` Deleted bool `json:"deleted"`
DeletedAt *misc.RFC8601DateTime `json:"deleted_at"` DeletedAt *util.RFC8601DateTime `json:"deleted_at"`
DiskFormat string `json:"disk_format"` DiskFormat string `json:"disk_format"`
ID string `json:"id"` ID string `json:"id"`
IsPublic bool `json:"is_public"` IsPublic bool `json:"is_public"`
@ -66,7 +67,7 @@ type DetailResponse struct {
MinRAM int64 `json:"min_ram"` MinRAM int64 `json:"min_ram"`
Name string `json:"name"` Name string `json:"name"`
Owner *string `json:"owner"` Owner *string `json:"owner"`
UpdatedAt misc.RFC8601DateTime `json:"updated_at"` UpdatedAt util.RFC8601DateTime `json:"updated_at"`
Properties map[string]string `json:"properties"` Properties map[string]string `json:"properties"`
Protected bool `json:"protected"` Protected bool `json:"protected"`
Status string `json:"status"` Status string `json:"status"`
@ -146,7 +147,7 @@ func (imageService Service) queryImages(includeDetails bool, imagesResponseConta
return err return err
} }
err = misc.GetJSON(reqURL.String(), imageService.TokenID, imageService.Client, &imagesResponseContainer) err = util.GetJSON(reqURL.String(), imageService.TokenID, imageService.Client, &imagesResponseContainer)
if err != nil { if err != nil {
return err return err
} }

View File

@ -17,12 +17,13 @@ package image_test
import ( import (
"errors" "errors"
"git.openstack.org/stackforge/golang-client.git/image/v1"
"git.openstack.org/stackforge/golang-client.git/misc"
"git.openstack.org/stackforge/golang-client.git/testUtil"
"net/http" "net/http"
"strings" "strings"
"testing" "testing"
"git.openstack.org/stackforge/golang-client.git/image/v1"
"git.openstack.org/stackforge/golang-client.git/testUtil"
"git.openstack.org/stackforge/golang-client.git/util"
) )
var tokn = "eaaafd18-0fed-4b3a-81b4-663c99ec1cbb" var tokn = "eaaafd18-0fed-4b3a-81b4-663c99ec1cbb"
@ -61,8 +62,8 @@ func TestListImageDetails(t *testing.T) {
if len(images) != 2 { if len(images) != 2 {
t.Error(errors.New("Incorrect number of images found")) t.Error(errors.New("Incorrect number of images found"))
} }
createdAt, _ := misc.NewDateTime(`"2014-09-29T14:44:31"`) createdAt, _ := util.NewDateTime(`"2014-09-29T14:44:31"`)
updatedAt, _ := misc.NewDateTime(`"2014-09-29T15:33:37"`) updatedAt, _ := util.NewDateTime(`"2014-09-29T15:33:37"`)
owner := "10014302369510" owner := "10014302369510"
virtualSize := int64(2525125) virtualSize := int64(2525125)
expectedImageDetail := image.DetailResponse{ expectedImageDetail := image.DetailResponse{

View File

@ -15,11 +15,12 @@
package objectstorage package objectstorage
import ( import (
"git.openstack.org/stackforge/golang-client.git/misc"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
"git.openstack.org/stackforge/golang-client.git/util"
) )
var zeroByte = &([]byte{}) //pointer to empty []byte var zeroByte = &([]byte{}) //pointer to empty []byte
@ -86,12 +87,12 @@ func ListObjects(limit int64,
if delim != "" { if delim != "" {
query += "&delimiter=" + url.QueryEscape(delim) query += "&delimiter=" + url.QueryEscape(delim)
} }
resp, err := misc.CallAPI("GET", conURL+query, zeroByte, resp, err := util.CallAPI("GET", conURL+query, zeroByte,
"X-Auth-Token", token) "X-Auth-Token", token)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = misc.CheckHTTPResponseStatusCode(resp); err != nil { if err = util.CheckHTTPResponseStatusCode(resp); err != nil {
return nil, err return nil, err
} }
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
@ -108,24 +109,24 @@ func ListObjects(limit int64,
func PutObject(fContent *[]byte, url, token string, s ...string) (err error) { func PutObject(fContent *[]byte, url, token string, s ...string) (err error) {
s = append(s, "X-Auth-Token") s = append(s, "X-Auth-Token")
s = append(s, token) s = append(s, token)
resp, err := misc.CallAPI("PUT", url, fContent, s...) resp, err := util.CallAPI("PUT", url, fContent, s...)
if err != nil { if err != nil {
return err return err
} }
return misc.CheckHTTPResponseStatusCode(resp) return util.CheckHTTPResponseStatusCode(resp)
} }
//CopyObject calls the OpenStack copy object API using previously obtained //CopyObject calls the OpenStack copy object API using previously obtained
//token. Note from API doc: "The destination container must exist before //token. Note from API doc: "The destination container must exist before
//attempting the copy." //attempting the copy."
func CopyObject(srcURL, destURL, token string) (err error) { func CopyObject(srcURL, destURL, token string) (err error) {
resp, err := misc.CallAPI("COPY", srcURL, zeroByte, resp, err := util.CallAPI("COPY", srcURL, zeroByte,
"X-Auth-Token", token, "X-Auth-Token", token,
"Destination", destURL) "Destination", destURL)
if err != nil { if err != nil {
return err return err
} }
return misc.CheckHTTPResponseStatusCode(resp) return util.CheckHTTPResponseStatusCode(resp)
} }
//DeleteObject calls the OpenStack delete object API using //DeleteObject calls the OpenStack delete object API using
@ -137,11 +138,11 @@ func CopyObject(srcURL, destURL, token string) (err error) {
//remove an object and you have five total versions of it, you must DELETE it //remove an object and you have five total versions of it, you must DELETE it
//five times." //five times."
func DeleteObject(url, token string) (err error) { func DeleteObject(url, token string) (err error) {
resp, err := misc.CallAPI("DELETE", url, zeroByte, "X-Auth-Token", token) resp, err := util.CallAPI("DELETE", url, zeroByte, "X-Auth-Token", token)
if err != nil { if err != nil {
return err return err
} }
return misc.CheckHTTPResponseStatusCode(resp) return util.CheckHTTPResponseStatusCode(resp)
} }
//SetObjectMeta calls the OpenStack API to create/update meta data for //SetObjectMeta calls the OpenStack API to create/update meta data for
@ -149,21 +150,21 @@ func DeleteObject(url, token string) (err error) {
func SetObjectMeta(url string, token string, s ...string) (err error) { func SetObjectMeta(url string, token string, s ...string) (err error) {
s = append(s, "X-Auth-Token") s = append(s, "X-Auth-Token")
s = append(s, token) s = append(s, token)
resp, err := misc.CallAPI("POST", url, zeroByte, s...) resp, err := util.CallAPI("POST", url, zeroByte, s...)
if err != nil { if err != nil {
return err return err
} }
return misc.CheckHTTPResponseStatusCode(resp) return util.CheckHTTPResponseStatusCode(resp)
} }
//GetObjectMeta calls the OpenStack retrieve object metadata API using //GetObjectMeta calls the OpenStack retrieve object metadata API using
//previously obtained token. //previously obtained token.
func GetObjectMeta(url, token string) (http.Header, error) { func GetObjectMeta(url, token string) (http.Header, error) {
resp, err := misc.CallAPI("HEAD", url, zeroByte, "X-Auth-Token", token) resp, err := util.CallAPI("HEAD", url, zeroByte, "X-Auth-Token", token)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return resp.Header, misc.CheckHTTPResponseStatusCode(resp) return resp.Header, util.CheckHTTPResponseStatusCode(resp)
} }
//GetObject calls the OpenStack retrieve object API using previously //GetObject calls the OpenStack retrieve object API using previously
@ -174,11 +175,11 @@ func GetObjectMeta(url, token string) (http.Header, error) {
//effectively executes GetObjectMeta also in addition to getting the //effectively executes GetObjectMeta also in addition to getting the
//object content. //object content.
func GetObject(url, token string) (http.Header, []byte, error) { func GetObject(url, token string) (http.Header, []byte, error) {
resp, err := misc.CallAPI("GET", url, zeroByte, "X-Auth-Token", token) resp, err := util.CallAPI("GET", url, zeroByte, "X-Auth-Token", token)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if err = misc.CheckHTTPResponseStatusCode(resp); err != nil { if err = util.CheckHTTPResponseStatusCode(resp); err != nil {
return nil, nil, err return nil, nil, err
} }
var body []byte var body []byte

4
openstack/README.md Normal file
View File

@ -0,0 +1,4 @@
openstack
=========
`openstack` is the API to an OpenStack cloud.

View File

@ -12,7 +12,7 @@
// License for the specific language governing permissions and limitations // License for the specific language governing permissions and limitations
// under the License. // under the License.
package misc package util
import ( import (
"time" "time"

View File

@ -12,19 +12,20 @@
// License for the specific language governing permissions and limitations // License for the specific language governing permissions and limitations
// under the License. // under the License.
package misc_test package util_test
import ( import (
"encoding/json" "encoding/json"
"git.openstack.org/stackforge/golang-client.git/misc"
"git.openstack.org/stackforge/golang-client.git/testUtil"
"testing" "testing"
"time" "time"
"git.openstack.org/stackforge/golang-client.git/testUtil"
"git.openstack.org/stackforge/golang-client.git/util"
) )
var testValue = `{"created_at":"2014-09-29T14:44:31"}` var testValue = `{"created_at":"2014-09-29T14:44:31"}`
var testTime, _ = time.Parse(`"2006-01-02T15:04:05"`, `"2014-09-29T14:44:31"`) var testTime, _ = time.Parse(`"2006-01-02T15:04:05"`, `"2014-09-29T14:44:31"`)
var timeTestValue = timeTest{CreatedAt: misc.RFC8601DateTime{testTime}} var timeTestValue = timeTest{CreatedAt: util.RFC8601DateTime{testTime}}
func TestMarshalTimeTest(t *testing.T) { func TestMarshalTimeTest(t *testing.T) {
bytes, _ := json.Marshal(timeTestValue) bytes, _ := json.Marshal(timeTestValue)
@ -54,5 +55,5 @@ func TestUnmarshalInvalidDateTimeFormatTimeTest(t *testing.T) {
} }
type timeTest struct { type timeTest struct {
CreatedAt misc.RFC8601DateTime `json:"created_at"` CreatedAt util.RFC8601DateTime `json:"created_at"`
} }

View File

@ -12,7 +12,7 @@
// License for the specific language governing permissions and limitations // License for the specific language governing permissions and limitations
// under the License. // under the License.
package misc package util
import ( import (
"bytes" "bytes"

View File

@ -12,18 +12,19 @@
// License for the specific language governing permissions and limitations // License for the specific language governing permissions and limitations
// under the License. // under the License.
package misc_test package util_test
import ( import (
"bytes" "bytes"
"errors" "errors"
"git.openstack.org/stackforge/golang-client.git/misc"
"git.openstack.org/stackforge/golang-client.git/testUtil"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"strconv" "strconv"
"testing" "testing"
"git.openstack.org/stackforge/golang-client.git/testUtil"
"git.openstack.org/stackforge/golang-client.git/util"
) )
var token = "2350971-5716-8165" var token = "2350971-5716-8165"
@ -32,7 +33,7 @@ func TestDelete(t *testing.T) {
var apiServer = testUtil.CreateDeleteTestRequestServer(t, token, "/other") var apiServer = testUtil.CreateDeleteTestRequestServer(t, token, "/other")
defer apiServer.Close() defer apiServer.Close()
err := misc.Delete(apiServer.URL+"/other", token, *http.DefaultClient) err := util.Delete(apiServer.URL+"/other", token, *http.DefaultClient)
testUtil.IsNil(t, err) testUtil.IsNil(t, err)
} }
@ -42,7 +43,7 @@ func TestPostJsonWithValidResponse(t *testing.T) {
actual := TestStruct{} actual := TestStruct{}
ti := TestStruct{ID: "id1", Name: "name"} ti := TestStruct{ID: "id1", Name: "name"}
err := misc.PostJSON(apiServer.URL, token, *http.DefaultClient, ti, &actual) err := util.PostJSON(apiServer.URL, token, *http.DefaultClient, ti, &actual)
testUtil.IsNil(t, err) testUtil.IsNil(t, err)
expected := TestStruct{ID: "id1", Name: "Chris"} expected := TestStruct{ID: "id1", Name: "Chris"}
@ -59,13 +60,13 @@ func TestCallAPI(t *testing.T) {
w.WriteHeader(200) //ok w.WriteHeader(200) //ok
})) }))
zeroByte := &([]byte{}) zeroByte := &([]byte{})
if _, err := misc.CallAPI("HEAD", apiServer.URL, zeroByte, "X-Auth-Token", tokn); err != nil { if _, err := util.CallAPI("HEAD", apiServer.URL, zeroByte, "X-Auth-Token", tokn); err != nil {
t.Error(err) t.Error(err)
} }
if _, err := misc.CallAPI("DELETE", apiServer.URL, zeroByte, "X-Auth-Token", tokn); err != nil { if _, err := util.CallAPI("DELETE", apiServer.URL, zeroByte, "X-Auth-Token", tokn); err != nil {
t.Error(err) t.Error(err)
} }
if _, err := misc.CallAPI("POST", apiServer.URL, zeroByte, "X-Auth-Token", tokn); err != nil { if _, err := util.CallAPI("POST", apiServer.URL, zeroByte, "X-Auth-Token", tokn); err != nil {
t.Error(err) t.Error(err)
} }
} }
@ -89,7 +90,7 @@ func TestCallAPIGetContent(t *testing.T) {
w.Write(body) w.Write(body)
})) }))
var resp *http.Response var resp *http.Response
if resp, err = misc.CallAPI("GET", apiServer.URL, &fContent, "X-Auth-Token", tokn, if resp, err = util.CallAPI("GET", apiServer.URL, &fContent, "X-Auth-Token", tokn,
"Etag", "md5hash-blahblah"); err != nil { "Etag", "md5hash-blahblah"); err != nil {
t.Error(err) t.Error(err)
} }
@ -128,7 +129,7 @@ func TestCallAPIPutContent(t *testing.T) {
} }
w.WriteHeader(200) w.WriteHeader(200)
})) }))
if _, err = misc.CallAPI("PUT", apiServer.URL, &fContent, "X-Auth-Token", tokn); err != nil { if _, err = util.CallAPI("PUT", apiServer.URL, &fContent, "X-Auth-Token", tokn); err != nil {
t.Error(err) t.Error(err)
} }
} }