mirror of
https://github.com/cloudflare/redoctober.git
synced 2026-01-08 15:21:50 +00:00
169 lines
4.3 KiB
Go
169 lines
4.3 KiB
Go
// Package order manages the bookkeeping and utilies required
|
|
// for users to create an 'order' meaning they have requested
|
|
// delegations for a certain resource.
|
|
//
|
|
// Copyright (c) 2016 CloudFlare, Inc.
|
|
package order
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/cloudflare/redoctober/hipchat"
|
|
)
|
|
|
|
const (
|
|
NewOrder = "%s has created an order for the label %s. requesting %d delegations for %s"
|
|
NewOrderLink = "@%s - https://%s?%s"
|
|
OrderFulfilled = "%s has had order %s fulfilled."
|
|
NewDelegation = "%s has delegated the label %s to %s (per order %s) for %s"
|
|
)
|
|
|
|
type Order struct {
|
|
Creator string
|
|
Users []string
|
|
Num string
|
|
|
|
TimeRequested time.Time
|
|
DurationRequested time.Duration
|
|
Delegated int
|
|
OwnersDelegated []string
|
|
Owners []string
|
|
Labels []string
|
|
}
|
|
|
|
type OrderIndex struct {
|
|
OrderFor string
|
|
|
|
OrderId string
|
|
OrderOwners []string
|
|
}
|
|
|
|
// Orders represents a mapping of Order IDs to Orders. This structure
|
|
// is useful for looking up information about individual Orders and
|
|
// whether or not an order has been fulfilled. Orders that have been
|
|
// fulfilled will be removed from the structure.
|
|
type Orderer struct {
|
|
Orders map[string]Order
|
|
Hipchat hipchat.HipchatClient
|
|
AlternateName string
|
|
}
|
|
|
|
func CreateOrder(name, orderNum string, time time.Time, duration time.Duration, adminsDelegated, contacts, users, labels []string, numDelegated int) (ord Order) {
|
|
ord.Creator = name
|
|
ord.Num = orderNum
|
|
ord.Labels = labels
|
|
ord.TimeRequested = time
|
|
ord.DurationRequested = duration
|
|
ord.OwnersDelegated = adminsDelegated
|
|
ord.Owners = contacts
|
|
ord.Delegated = numDelegated
|
|
ord.Users = users
|
|
return
|
|
}
|
|
|
|
func GenerateNum() (num string) {
|
|
b := make([]byte, 12)
|
|
rand.Read(b)
|
|
return hex.EncodeToString(b)
|
|
}
|
|
|
|
// NewOrder will create a new map of Orders
|
|
func NewOrderer(hipchatClient hipchat.HipchatClient) (o Orderer) {
|
|
o.Orders = make(map[string]Order)
|
|
o.Hipchat = hipchatClient
|
|
o.AlternateName = "HipchatName"
|
|
return
|
|
}
|
|
|
|
// notify is a generic function for using a notifier, but it checks to make
|
|
// sure that there is a notifier available, since there won't always be.
|
|
func notify(o *Orderer, msg, color string) {
|
|
o.Hipchat.Notify(msg, color)
|
|
}
|
|
func (o *Orderer) NotifyNewOrder(duration, orderNum string, names, labels []string, uses int, owners map[string]string) {
|
|
labelList := ""
|
|
for i, label := range labels {
|
|
if i == 0 {
|
|
labelList += label
|
|
} else {
|
|
// Never include spaces in something go URI encodes. Go will
|
|
// add a + to the string, instead of a %20
|
|
labelList += "," + label
|
|
}
|
|
}
|
|
nameList := ""
|
|
for i, name := range names {
|
|
if i == 0 {
|
|
nameList += name
|
|
} else {
|
|
// Never include spaces in something go URI encodes. Go will
|
|
// add a + to the string, instead of a %20
|
|
nameList += "," + name
|
|
}
|
|
}
|
|
|
|
n := fmt.Sprintf(NewOrder, nameList, labelList, uses, duration)
|
|
notify(o, n, hipchat.RedBackground)
|
|
for owner, hipchatName := range owners {
|
|
queryParams := url.Values{
|
|
"delegator": {owner},
|
|
"label": {labelList},
|
|
"duration": {duration},
|
|
"uses": {strconv.Itoa(uses)},
|
|
"ordernum": {orderNum},
|
|
"delegatee": {nameList},
|
|
}.Encode()
|
|
notify(o, fmt.Sprintf(NewOrderLink, hipchatName, o.Hipchat.RoHost, queryParams), hipchat.GreenBackground)
|
|
}
|
|
}
|
|
|
|
func (o *Orderer) NotifyDelegation(delegator, delegatee, orderNum, duration string, labels []string) {
|
|
labelList := ""
|
|
for i, label := range labels {
|
|
if i == 0 {
|
|
labelList += label
|
|
} else {
|
|
labelList += ", " + label
|
|
}
|
|
}
|
|
n := fmt.Sprintf(NewDelegation, delegator, labelList, delegatee, orderNum, duration)
|
|
notify(o, n, hipchat.YellowBackground)
|
|
}
|
|
func (o *Orderer) NotifyOrderFulfilled(name, orderNum string) {
|
|
n := fmt.Sprintf(OrderFulfilled, name, orderNum)
|
|
notify(o, n, hipchat.PurpleBackground)
|
|
}
|
|
|
|
func (o *Orderer) FindOrder(user string, labels []string) (string, bool) {
|
|
for key, order := range o.Orders {
|
|
foundLabel := false
|
|
foundUser := false
|
|
for _, orderUser := range order.Users {
|
|
if orderUser == user {
|
|
foundUser = true
|
|
}
|
|
}
|
|
if !foundUser {
|
|
continue
|
|
}
|
|
for _, ol := range order.Labels {
|
|
foundLabel = false
|
|
for _, il := range labels {
|
|
if il == ol {
|
|
foundLabel = true
|
|
}
|
|
}
|
|
}
|
|
if !foundLabel {
|
|
continue
|
|
}
|
|
return key, true
|
|
}
|
|
return "", false
|
|
}
|