aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md63
-rw-r--r--account.go89
-rw-r--r--doc.go62
3 files changed, 214 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..823537c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,63 @@
+# Schwift
+
+this is a Go client library for [OpenStack Swift](https://github.com/openstack/swift). I made this after growing
+frustrated with the bad API design of [`ncw/swift`](https://github.com/ncw/swift).
+
+<p style="color:red;font-weight:bold">WARNING: This is in a pre-alpha stage and neither complete nor tested.</p>
+
+## Installation
+
+You can get this with `go get github.com/majewsky/schwift`. When using this in an application, vendoring is recommended.
+
+## Usage
+
+This library uses [Gophercloud](https://github.com/gophercloud/gophercloud) to handle authentication, so to use Schwift, you have to first build a `gophercloud.ServiceClient` and then pass that to `schwift.Account()` to get a handle on the Swift account.
+
+For example, to connect to Swift using OpenStack Keystone authentication:
+
+```go
+import (
+ "log"
+
+ "github.com/gophercloud/gophercloud"
+ "github.com/gophercloud/gophercloud/openstack"
+ "github.com/majewsky/schwift"
+)
+
+authOptions, err := openstack.AuthOptionsFromEnv()
+handle(err)
+provider, err := openstack.AuthenticatedClient(authOptions)
+handle(err)
+client, err := openstack.NewObjectStorageV1(provider, gophercloud.EndpointOpts {})
+handle(err)
+
+account, err := schwift.AccountFromClient(client)
+handle(err)
+```
+
+To connect to Swift using Swift's built-in authentication:
+
+```go
+import (
+ "log"
+
+ "github.com/gophercloud/gophercloud"
+ "github.com/gophercloud/gophercloud/openstack"
+ "github.com/gophercloud/gophercloud/openstack/objectstore/v1/swauth"
+ "github.com/majewsky/schwift"
+)
+
+provider, err := openstack.NewClient("http://swift.example.com:8080")
+handle(err)
+client, err := swauth.NewObjectStorageV1(provider, swauth.AuthOpts {
+ User: "project:user",
+ Key: "password",
+})
+handle(err)
+
+account, err := schwift.AccountFromClient(client)
+handle(err)
+```
+
+From this point, follow the [API documentation](https://godoc.org/github.com/majewsky/schwift) for what you can do with
+the `schwift.Account` object.
diff --git a/account.go b/account.go
new file mode 100644
index 0000000..6672a62
--- /dev/null
+++ b/account.go
@@ -0,0 +1,89 @@
+/******************************************************************************
+*
+* Copyright 2018 Stefan Majewsky <majewsky@gmx.net>
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************************/
+
+package schwift
+
+import (
+ "fmt"
+ "regexp"
+
+ "github.com/gophercloud/gophercloud"
+)
+
+//Account represents a Swift account.
+type Account struct {
+ client *gophercloud.ServiceClient
+ //URL parts
+ baseURL string
+ name string
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// interface to Gophercloud, endpoint inspection and manipulation
+
+var endpointURLRegexp = regexp.MustCompile(`^(.*/)v1/(.*)/$`)
+
+//AccountFromClient takes a gophercloud.ServiceClient which wraps a Swift
+//endpoint, and returns the Account instance corresponding to the account or
+//project that this client is connected to.
+func AccountFromClient(client *gophercloud.ServiceClient) (*Account, error) {
+ match := endpointURLRegexp.FindStringSubmatch(client.Endpoint)
+ if match == nil {
+ return nil, fmt.Errorf(`schwift.AccountFromClient(): invalid Swift endpoint URL: cannot find "/v1/" in %q`, client.Endpoint)
+ }
+ return &Account{
+ client: client,
+ baseURL: match[1],
+ name: match[2],
+ }, nil
+}
+
+//SwitchAccount returns a handle on a different account on the same server. Note
+//that you need reseller permissions to access accounts other than that where
+//you originally authenticated. This method does not check whether the account
+//actually exists.
+//
+//The account name is usually the project name with an additional "AUTH_"
+//prefix.
+func (a *Account) SwitchAccount(accountName string) *Account {
+ clonedClient := *a.client
+ clonedClient.Endpoint = a.baseURL + "v1/" + accountName + "/"
+ return &Account{
+ client: &clonedClient,
+ baseURL: a.baseURL,
+ name: accountName,
+ }
+}
+
+//Name returns the name of the account (usually the prefix "AUTH_" followed by
+//the project ID).
+func (a *Account) Name() string {
+ return a.name
+}
+
+//Client returns the gophercloud.ServiceClient which is used to make requests
+//against this account.
+func (a *Account) Client() *gophercloud.ServiceClient {
+ return a.client
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// account metadata
+
+////////////////////////////////////////////////////////////////////////////////
+// container listing
diff --git a/doc.go b/doc.go
new file mode 100644
index 0000000..d4cb6bd
--- /dev/null
+++ b/doc.go
@@ -0,0 +1,62 @@
+/******************************************************************************
+*
+* Copyright 2018 Stefan Majewsky <majewsky@gmx.net>
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************************/
+
+/*
+
+Package schwift is a client library for OpenStack Swift
+(https://github.com/openstack/swift, https://openstack.org).
+
+It uses Gophercloud (https://github.com/gophercloud/gophercloud) for
+authentication, so you usually start by obtaining a gophercloud.ServiceClient
+for Swift like so:
+
+ authOptions, err := openstack.AuthOptionsFromEnv()
+ provider, err := openstack.AuthenticatedClient(authOptions)
+ client, err := openstack.NewObjectStorageV1(provider, gophercloud.EndpointOpts {})
+
+Or, if you use Swift's built-in authentication instead of Keystone:
+
+ provider, err := openstack.NewClient("http://swift.example.com:8080")
+ client, err := swauth.NewObjectStorageV1(provider, swauth.AuthOpts {
+ User: "project:user",
+ Key: "password",
+ })
+
+Then, in both cases, you use schwift.AccountFromClient() to obtain a
+schwift.Account instance, from which point you have access to all of schwift's
+API.
+
+Caching
+
+When a GET or HEAD request is sent by an Account, Container or Object instance,
+the metadata associated with that thing will be stored in that instance. You
+can therefore access metadata attributes directly via their accessors and
+everything just works, i.e. the first call to a getter will retrieve the
+metadata:
+
+ obj := account.Container("foo").Object("bar")
+
+ t, err := obj.LastModified() //sends HTTP request "HEAD <storage-url>/foo/bar"
+ assert(err == nil)
+ t, err := obj.LastModified() //returns cached value immediately
+
+If this behavior is not desired, the Invalidate() method can be used to clear
+caches on any Account, Container or Object instance.
+
+*/
+package schwift