Initial commit

This commit is contained in:
Lena Fuhrimann 2016-12-18 22:54:21 +01:00
commit 03e9afc888
9 changed files with 243 additions and 0 deletions

2
.cfignore Normal file
View file

@ -0,0 +1,2 @@
vendor
README.md

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
vendor
glide.lock

10
README.md Normal file
View file

@ -0,0 +1,10 @@
# S3 Manager
Manage S3 buckets from any provider.
## Environment Variables
* `S3_ACCESS_KEY_ID`
* `S3_SECRET_ACCESS_KEY`
* `S3_ENDPOINT`: Optional. In case you are using a different S3 provider than AWS. Defaults to `s3.amazonaws.com`
* `V2_SIGNING`: Optional. In case your S3 provider still uses V2 Signing, set this to `true`

4
glide.yaml Normal file
View file

@ -0,0 +1,4 @@
package: github.com/mastertinner/s3manager
import:
- package: github.com/minio/minio-go
version: ^2.0.2

64
handlers.go Normal file
View file

@ -0,0 +1,64 @@
package main
import (
"fmt"
"html/template"
"net/http"
"path"
"strings"
minio "github.com/minio/minio-go"
)
// indexHandler handles the main page
func indexHandler(w http.ResponseWriter, r *http.Request) {
lp := path.Join("templates", "layout.html")
ip := path.Join("templates", "index.html")
t, err := template.ParseFiles(lp, ip)
if err != nil {
panic(err)
}
buckets, err := minioClient.ListBuckets()
if err != nil {
panic(err)
}
err = t.ExecuteTemplate(w, "layout", buckets)
if err != nil {
panic(err)
}
}
// bucketHandler handles the main page
func bucketHandler(w http.ResponseWriter, r *http.Request) {
bucket := strings.Split(r.URL.Path, "/")[2]
var objects []minio.ObjectInfo
lp := path.Join("templates", "layout.html")
bp := path.Join("templates", "bucket.html")
t, err := template.ParseFiles(lp, bp)
if err != nil {
panic(err)
}
// Create a done channel to control 'ListObjectsV2' go routine.
doneCh := make(chan struct{})
objectCh := minioClient.ListObjectsV2(bucket, "", false, doneCh)
for object := range objectCh {
if object.Err != nil {
fmt.Println(object.Err)
return
}
objects = append(objects, object)
}
err = t.ExecuteTemplate(w, "layout", objects)
if err != nil {
panic(err)
}
}

48
main.go Normal file
View file

@ -0,0 +1,48 @@
package main
import (
"log"
"net/http"
"os"
"github.com/minio/minio-go"
)
var minioClient *minio.Client
func main() {
var err error
port := os.Getenv("PORT")
if len(port) == 0 {
port = "8080"
}
s3AccessKeyID := os.Getenv("S3_ACCESS_KEY_ID")
if len(s3AccessKeyID) == 0 {
log.Fatalln("Please set S3_ACCESS_KEY_ID")
}
s3SecretAccessKey := os.Getenv("S3_SECRET_ACCESS_KEY")
if len(s3SecretAccessKey) == 0 {
log.Fatalln("Please set S3_SECRET_ACCESS_KEY")
}
s3Endpoint := os.Getenv("S3_ENDPOINT")
if len(s3Endpoint) == 0 {
s3Endpoint = "s3.amazonaws.com"
}
if os.Getenv("V2_SIGNING") == "true" {
minioClient, err = minio.NewV2(s3Endpoint, s3AccessKeyID, s3SecretAccessKey, true)
} else {
minioClient, err = minio.New(s3Endpoint, s3AccessKeyID, s3SecretAccessKey, true)
}
if err != nil {
panic(err)
}
http.HandleFunc("/", indexHandler)
http.HandleFunc("/buckets/", bucketHandler)
log.Fatal(http.ListenAndServe(":"+port, nil))
}

25
templates/bucket.html Normal file
View file

@ -0,0 +1,25 @@
{{ define "content" }}
<table class="striped">
<thead>
<tr>
<th>Key</th>
<th>Size</th>
<th>Owner</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
{{ range $object := . }}
<tr>
<td>{{ $object.Key }}</td>
<td>{{ $object.Size }} bytes</td>
<td>{{ $object.Owner }}</td>
<td>{{ $object.LastModified }}</td>
</tr>
{{ end }}
</tbody>
</table>
{{ end }}

54
templates/index.html Normal file
View file

@ -0,0 +1,54 @@
{{ define "content" }}
<div class="row">
<div class="col m12 l6">
{{ range $bucket := . }}
<a href="/buckets/{{ $bucket.Name }}" style="color: black;">
<div class="card">
<div class="card-content">
<div class="row" style="margin-bottom: 0;">
<div class="col">
<i class="material-icons large">cloud_circle</i>
</div>
<div class="col">
<span class="card-title">
{{ $bucket.Name }}
</span>
<p style="color: gray;">Created on {{ $bucket.CreationDate }}</p>
</div>
</div>
</div>
</div>
</a>
{{ end }}
</div>
</div>
<div class="fixed-action-btn">
<a class="btn-floating btn-large red" href="#modal-create-bucket">
<i class="large material-icons">add</i>
</a>
</div>
<div id="modal-create-bucket" class="modal">
<div class="modal-content">
<h4>Create Bucket</h4>
<br>
<div class="row">
<div class="col s6">
<form action="/api/buckets" method="POST">
<div class="input-field">
<input placeholder="My Bucket" id="name" type="text">
<label for="name">Name</label>
</div>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Create</a>
<a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Cancel</a>
</div>
</div>
{{ end }}

34
templates/layout.html Normal file
View file

@ -0,0 +1,34 @@
{{ define "layout" }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
<title>S3 Manager</title>
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css">
</head>
<body>
<nav class="purple" role="navigation">
<div class="nav-wrapper container">
<a href="/" class="brand-logo">S3 Manager</a>
</div>
</nav>
<div class="container">
<div class="section">
{{ template "content" . }}
</div>
</div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js"></script>
</body>
</html>
{{ end }}