Skip to content

Instantly share code, notes, and snippets.

@zackmdavis
Created May 13, 2016 21:46
Show Gist options
  • Save zackmdavis/edd037db07deec1e613438495ae2281d to your computer and use it in GitHub Desktop.
Save zackmdavis/edd037db07deec1e613438495ae2281d to your computer and use it in GitHub Desktop.
writing Static Large Objects to Swift from Go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
type objectDescription struct {
Path string `json:"path"`
Etag string `json:"etag"`
Size interface{} `json:"size_bytes"`
}
func v1Auth(clusterURL string, username string, password string) (storageURL string, authToken string, err error) {
client := &http.Client{}
authURL := fmt.Sprintf("%v/auth/v1.0", clusterURL)
req, err := http.NewRequest("GET", authURL, nil)
if err != nil {
return "", "", err
}
req.Header.Set("X-Auth-User", username)
req.Header.Set("X-Auth-Key", password)
resp, err := client.Do(req)
if err != nil {
return "", "", err
}
if resp.StatusCode != 200 {
return "", "", fmt.Errorf("auth request failed: %v", resp.Status)
}
storageURL = resp.Header["X-Storage-Url"][0]
authToken = resp.Header["X-Auth-Token"][0]
return storageURL, authToken, nil
}
func putObject(object io.Reader, storageURL string, authToken string, container string, name string) (objectDescription, error) {
client := &http.Client{}
URL := fmt.Sprintf("%v/%v/%v", storageURL, container, name)
req, err := http.NewRequest("PUT", URL, object)
if err != nil {
return objectDescription{}, err
}
req.Header.Set("X-Auth-Token", authToken)
resp, err := client.Do(req)
if err != nil {
return objectDescription{}, err
}
if resp.StatusCode != 201 {
return objectDescription{}, fmt.Errorf("PUT request failed: %v", resp.Status)
}
return objectDescription{
Path: fmt.Sprintf("%v/%v", container, name),
Etag: resp.Header["Etag"][0],
Size: nil,
}, nil
}
func putStaticLargeObject(segments []io.Reader, storageURL string, authToken string, container string, name string) error {
segmentDescriptions := make([]objectDescription, 0, len(segments))
for i, segment := range segments {
desc, err := putObject(segment, storageURL, authToken, container, fmt.Sprintf("%v%v", name, i))
if err != nil {
return err
}
segmentDescriptions = append(segmentDescriptions, desc)
}
manifest, err := json.Marshal(segmentDescriptions)
if err != nil {
return err
}
client := &http.Client{}
URL := fmt.Sprintf("%v/%v/%v?multipart-manifest=put", storageURL, container, name)
req, err := http.NewRequest("PUT", URL, bytes.NewReader(manifest))
if err != nil {
return err
}
req.Header.Set("X-Auth-Token", authToken)
resp, err := client.Do(req)
if err != nil {
return err
}
if resp.StatusCode != 201 {
return fmt.Errorf("multipart manifest PUT failed: %v", resp.Status)
}
return nil
}
func main() {
// example usage; your setup may vary
storageURL, authToken, err := v1Auth("http://192.168.22.110", "Jennifer_Userton", "troubleshoot")
if err != nil {
panic(err)
}
fs := make([]io.Reader, 0, 3)
for _, filename := range []string{"foo", "bar", "quux"} {
f, err := os.Open(fmt.Sprintf("%v.txt", filename))
if err != nil {
panic(err)
}
fs = append(fs, f)
}
err = putStaticLargeObject(fs, storageURL, authToken, "slo_container", "my_slo")
if err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment