aboutsummaryrefslogblamecommitdiff
path: root/garage.go
blob: 7cd879b84e9b4d8a347b3ee34bc49e93ef21b35d (plain) (tree)
1
2
3
4
5
6
7
8
9
10


            
                 

                                                                     
                                


                  

 
                                                    


                                                   
 

                                                    
 


                                                                                                      

 
                                                         








                                                                             


                                                           







                                                                      

 
                                                                 










                                                                                              


                         
                                                                        
                               


                                           
                                 


                                                                                           
                                                                                                 




                                        



                                                                     




                                                          

                 
 

                                                                                              
 
                                                                                                   






                                        

 











































                                                                                                                    
                                                           
                               
 

                                                                          
                                


                               


 


                                        

                                                                   
                                
         


                  
                                     
 
                                                                     

                                     

                      

                                              
                             
 
 
                                                                

                                     

                      
 
                                               
                       
                                                                          
                      

         

                                                                                             





                                                                     
                               
                  

 
                                                               

                                     

                      
 
                                               
                       
                                                                          
                      

         
                                        
 
                                                             
                               
                             

                                                            


                                                                    
 
                                                
                               
                                     
                                                   
                              

                 
                                                                                           

                      
 
                                   

 
                               
                                 

                             
 
 
                                                                   

                            

                                     

                      
 
                                               
                       
                                                                          
                      
         
 
                                           


                               
                                                            
                               



                                                                                                                   


                                                                                 

                                                                 


                 
 
                                             
                       
                                                                          
                      
         
 


                                                                          
                      
         
 
                                                             

                                                                     
                                        
 















































                                                                                                   
package main

import (
	"context"
	"fmt"
	garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang"
	"github.com/gorilla/mux"
	"log"
	"net/http"
	"strings"
)

func gadmin() (*garage.APIClient, context.Context) {
	// Set Host and other parameters
	configuration := garage.NewConfiguration()
	configuration.Host = config.S3AdminEndpoint

	// We can now generate a client
	client := garage.NewAPIClient(configuration)

	// Authentication is handled through the context pattern
	ctx := context.WithValue(context.Background(), garage.ContextAccessToken, config.S3AdminToken)
	return client, ctx
}

func grgCreateKey(name string) (*garage.KeyInfo, error) {
	client, ctx := gadmin()

	kr := garage.AddKeyRequest{Name: &name}
	resp, _, err := client.KeyApi.AddKey(ctx).AddKeyRequest(kr).Execute()
	if err != nil {
		fmt.Printf("%+v\n", err)
		return nil, err
	}
	return resp, nil
}

func grgGetKey(accessKey string) (*garage.KeyInfo, error) {
	client, ctx := gadmin()

	resp, _, err := client.KeyApi.GetKey(ctx, accessKey).Execute()
	if err != nil {
		fmt.Printf("%+v\n", err)
		return nil, err
	}
	return resp, nil
}

func grgCreateBucket(bucket string) (*garage.BucketInfo, error) {
	client, ctx := gadmin()

	br := garage.NewCreateBucketRequest()
	br.SetGlobalAlias(bucket)

	// Create Bucket
	binfo, _, err := client.BucketApi.CreateBucket(ctx).CreateBucketRequest(*br).Execute()
	if err != nil {
		fmt.Printf("%+v\n", err)
		return nil, err
	}
	return binfo, nil
}

func grgAllowKeyOnBucket(bid, gkey string) (*garage.BucketInfo, error) {
	client, ctx := gadmin()

	// Allow user's key
	ar := garage.AllowBucketKeyRequest{
		BucketId:    bid,
		AccessKeyId: gkey,
		Permissions: *garage.NewAllowBucketKeyRequestPermissions(true, true, true),
	}
	binfo, _, err := client.BucketApi.AllowBucketKey(ctx).AllowBucketKeyRequest(ar).Execute()
	if err != nil {
		fmt.Printf("%+v\n", err)
		return nil, err
	}

	return binfo, nil
}

func allowWebsiteDefault() *garage.UpdateBucketRequestWebsiteAccess {
	wr := garage.NewUpdateBucketRequestWebsiteAccess()
	wr.SetEnabled(true)
	wr.SetIndexDocument("index.html")
	wr.SetErrorDocument("error.html")

	return wr
}

func grgUpdateBucket(bid string, ur *garage.UpdateBucketRequest) (*garage.BucketInfo, error) {
	client, ctx := gadmin()

	binfo, _, err := client.BucketApi.UpdateBucket(ctx, bid).UpdateBucketRequest(*ur).Execute()
	if err != nil {
		fmt.Printf("%+v\n", err)
		return nil, err
	}

	// Return updated binfo
	return binfo, nil
}

func grgAddGlobalAlias(bid, alias string) (*garage.BucketInfo, error) {
	client, ctx := gadmin()

	resp, _, err := client.BucketApi.PutBucketGlobalAlias(ctx).Id(bid).Alias(alias).Execute()
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return resp, nil
}

func grgAddLocalAlias(bid, key, alias string) (*garage.BucketInfo, error) {
	client, ctx := gadmin()

	resp, _, err := client.BucketApi.PutBucketLocalAlias(ctx).Id(bid).AccessKeyId(key).Alias(alias).Execute()
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return resp, nil
}

func grgDelGlobalAlias(bid, alias string) (*garage.BucketInfo, error) {
	client, ctx := gadmin()

	resp, _, err := client.BucketApi.DeleteBucketGlobalAlias(ctx).Id(bid).Alias(alias).Execute()
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return resp, nil
}

func grgDelLocalAlias(bid, key, alias string) (*garage.BucketInfo, error) {
	client, ctx := gadmin()

	resp, _, err := client.BucketApi.DeleteBucketLocalAlias(ctx).Id(bid).AccessKeyId(key).Alias(alias).Execute()
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return resp, nil
}

func grgGetBucket(bid string) (*garage.BucketInfo, error) {
	client, ctx := gadmin()

	resp, _, err := client.BucketApi.GetBucketInfo(ctx, bid).Execute()
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return resp, nil

}

func grgDeleteBucket(bid string) error {
	client, ctx := gadmin()

	_, err := client.BucketApi.DeleteBucket(ctx, bid).Execute()
	if err != nil {
		log.Println(err)
	}
	return err
}

// --- Start page rendering functions

func handleWebsiteConfigure(w http.ResponseWriter, r *http.Request) {
	user := RequireUserHtml(w, r)
	if user == nil {
		return
	}

	tKey := getTemplate("garage_key.html")
	tKey.Execute(w, user)
}

func handleWebsiteList(w http.ResponseWriter, r *http.Request) {
	user := RequireUserHtml(w, r)
	if user == nil {
		return
	}

	ctrl, err := NewWebsiteController(user)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if len(ctrl.PrettyList) > 0 {
		http.Redirect(w, r, "/website/inspect/"+ctrl.PrettyList[0], http.StatusFound)
	} else {
		http.Redirect(w, r, "/website/new", http.StatusFound)
	}
}

type WebsiteNewTpl struct {
	Ctrl *WebsiteController
	Err  error
}

func handleWebsiteNew(w http.ResponseWriter, r *http.Request) {
	user := RequireUserHtml(w, r)
	if user == nil {
		return
	}

	ctrl, err := NewWebsiteController(user)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	tpl := &WebsiteNewTpl{ctrl, nil}

	tWebsiteNew := getTemplate("garage_website_new.html")
	if r.Method == "POST" {
		r.ParseForm()

		bucket := strings.Join(r.Form["bucket"], "")
		if bucket == "" {
			bucket = strings.Join(r.Form["bucket2"], "")
		}

		view, err := ctrl.Create(bucket)
		if err != nil {
			tpl.Err = err
			tWebsiteNew.Execute(w, tpl)
			return
		}

		http.Redirect(w, r, "/website/inspect/"+view.Name.Pretty, http.StatusFound)
		return
	}

	tWebsiteNew.Execute(w, tpl)
}

type WebsiteInspectTpl struct {
	Describe *WebsiteDescribe
	View     *WebsiteView
	Err      error
}

func handleWebsiteInspect(w http.ResponseWriter, r *http.Request) {
	var processErr error

	user := RequireUserHtml(w, r)
	if user == nil {
		return
	}

	ctrl, err := NewWebsiteController(user)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	bucketName := mux.Vars(r)["bucket"]

	if r.Method == "POST" {
		r.ParseForm()
		action := strings.Join(r.Form["action"], "")
		switch action {
		case "increase_quota":
			_, processErr = ctrl.Patch(bucketName, &WebsitePatch{Size: &user.Quota.WebsiteSizeBursted})
		case "delete_bucket":
			processErr = ctrl.Delete(bucketName)
			if processErr == nil {
				http.Redirect(w, r, "/website", http.StatusFound)
			}
		default:
			processErr = fmt.Errorf("Unknown action")
		}

	}

	view, err := ctrl.Inspect(bucketName)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	describe, err := ctrl.Describe()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	tpl := &WebsiteInspectTpl{describe, view, processErr}

	tWebsiteInspect := getTemplate("garage_website_inspect.html")
	tWebsiteInspect.Execute(w, &tpl)
}

func handleWebsiteVhost(w http.ResponseWriter, r *http.Request) {
	var processErr error

	user := RequireUserHtml(w, r)
	if user == nil {
		return
	}

	ctrl, err := NewWebsiteController(user)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	bucketName := mux.Vars(r)["bucket"]

	if r.Method == "POST" {
		r.ParseForm()

		bucket := strings.Join(r.Form["bucket"], "")
		if bucket == "" {
			bucket = strings.Join(r.Form["bucket2"], "")
		}

		view, processErr := ctrl.Patch(bucketName, &WebsitePatch{Vhost: &bucket})
		if processErr == nil {
			http.Redirect(w, r, "/website/inspect/"+view.Name.Pretty, http.StatusFound)
			return
		}
	}

	view, err := ctrl.Inspect(bucketName)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	describe, err := ctrl.Describe()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	tpl := &WebsiteInspectTpl{describe, view, processErr}
	tWebsiteEdit := getTemplate("garage_website_edit.html")
	tWebsiteEdit.Execute(w, &tpl)
}