diff options
Diffstat (limited to 'website.go')
-rw-r--r-- | website.go | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/website.go b/website.go new file mode 100644 index 0000000..c06ccbc --- /dev/null +++ b/website.go @@ -0,0 +1,211 @@ +package main + +import ( + "fmt" + "sort" + "strings" + garage "git.deuxfleurs.fr/garage-sdk/garage-admin-sdk-golang" +) + +var ( + ErrWebsiteNotFound = fmt.Errorf("Website not found") + ErrFetchBucketInfo = fmt.Errorf("Failed to fetch bucket information") + ErrWebsiteQuotaReached = fmt.Errorf("Can't create additional websites, quota reached") + ErrEmptyBucketName = fmt.Errorf("You can't create a website with an empty name") + ErrCantCreateBucket = fmt.Errorf("Can't create this bucket. Maybe another bucket already exists with this name or you have an invalid character") + ErrCantAllowKey = fmt.Errorf("Can't allow given key on the target bucket") + ErrCantConfigureBucket = fmt.Errorf("Unable to configure the bucket (activating website, adding quotas, etc.)") +) + +type QuotaStat struct { + Current int64 + Max int64 + Ratio float64 + Burstable bool +} +func NewQuotaStat(current, max int64, burstable bool) QuotaStat { + return QuotaStat { + Current: current, + Max: max, + Ratio: float64(current) / float64(max), + Burstable: burstable, + } +} +func (q *QuotaStat) IsFull() bool { + return q.Current >= q.Max +} +func (q *QuotaStat) Percent() int64 { + return int64(q.Ratio * 100) +} + +func (q *QuotaStat) PrettyCurrent() string { + return prettyValue(q.Current) +} +func (q *QuotaStat) PrettyMax() string { + return prettyValue(q.Max) +} + +func prettyValue(v int64) string { + if v < 1024 { + return fmt.Sprintf("%d octets", v) + } + v = v / 1024 + if v < 1024 { + return fmt.Sprintf("%d kio", v) + } + v = v / 1024 + if v < 1024 { + return fmt.Sprintf("%d Mio", v) + } + v = v / 1024 + if v < 1024 { + return fmt.Sprintf("%d Gio", v) + } + v = v / 1024 + return fmt.Sprintf("%d Tio", v) +} + +type WebsiteId struct { + Pretty string + Internal string + Alt []string + Expanded bool + Url string + +} +func NewWebsiteId(id string, aliases []string) *WebsiteId { + pretty := id + var alt []string + if len(aliases) > 0 { + pretty = aliases[0] + alt = aliases[1:] + } + expanded := strings.Contains(pretty, ".") + + url := pretty + if !expanded { + url = fmt.Sprintf("%s.web.deuxfleurs.fr", pretty) + } + + return &WebsiteId { pretty, id, alt, expanded, url } +} +func NewWebsiteIdFromBucketInfo(binfo *garage.BucketInfo) *WebsiteId { + return NewWebsiteId(*binfo.Id, binfo.GlobalAliases) +} + +type WebsiteController struct { + User *LoggedUser + WebsiteIdx map[string]*WebsiteId + PrettyList []string + WebsiteCount QuotaStat +} + +func NewWebsiteController(user *LoggedUser) (*WebsiteController, error) { + idx := map[string]*WebsiteId{} + var wlist []string + + keyInfo, err := user.S3KeyInfo() + if err != nil { + return nil, err + } + + for _, bckt := range(keyInfo.Buckets) { + if len(bckt.GlobalAliases) > 0 { + wid := NewWebsiteId(*bckt.Id, bckt.GlobalAliases) + idx[wid.Pretty] = wid + wlist = append(wlist, wid.Pretty) + } + } + sort.Strings(wlist) + + maxW := user.Quota.WebsiteCount + quota := NewQuotaStat(int64(len(wlist)), maxW, true) + + return &WebsiteController { user, idx, wlist, quota }, nil +} + +func (w *WebsiteController) List() []*WebsiteId { + r := make([]*WebsiteId, 0, len(w.PrettyList)) + for _, k := range w.PrettyList { + r = append(r, w.WebsiteIdx[k]) + } + return r +} + +func (w *WebsiteController) Inspect(pretty string) (*WebsiteView, error) { + website, ok := w.WebsiteIdx[pretty] + if !ok { + return nil, ErrWebsiteNotFound + } + + binfo, err := grgGetBucket(website.Internal) + if err != nil { + return nil, ErrFetchBucketInfo + } + + return NewWebsiteView(binfo), nil +} + +func (w *WebsiteController) Patch(patch *WebsitePatch) (*WebsiteView, error) { + return nil, nil +} + +func (w *WebsiteController) Create(pretty string) (*WebsiteView, error) { + if pretty == "" { + return nil, ErrEmptyBucketName + } + + if w.WebsiteCount.IsFull() { + return nil, ErrWebsiteQuotaReached + } + + binfo, err := grgCreateBucket(pretty) + if err != nil { + return nil, ErrCantCreateBucket + } + + s3key, err := w.User.S3KeyInfo() + if err != nil { + return nil, err + } + + binfo, err = grgAllowKeyOnBucket(*binfo.Id, *s3key.AccessKeyId) + if err != nil { + return nil, ErrCantAllowKey + } + + qr := w.User.Quota.DefaultWebsiteQuota() + wr := allowWebsiteDefault() + + ur := garage.NewUpdateBucketRequest() + ur.SetWebsiteAccess(*wr) + ur.SetQuotas(*qr) + + + binfo, err = grgUpdateBucket(*binfo.Id, ur) + if err != nil { + return nil, ErrCantConfigureBucket + } + + return NewWebsiteView(binfo), nil +} + + +type WebsiteView struct { + Name *WebsiteId + Size QuotaStat + Files QuotaStat +} + +func NewWebsiteView(binfo *garage.BucketInfo) *WebsiteView { + q := binfo.GetQuotas() + + wid := NewWebsiteIdFromBucketInfo(binfo) + size := NewQuotaStat(*binfo.Bytes, (&q).GetMaxSize(), true) + objects := NewQuotaStat(*binfo.Objects, (&q).GetMaxObjects(), false) + return &WebsiteView { wid, size, objects } +} + +type WebsitePatch struct { + size int64 +} |