1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
// Package order manages the bookkeeping and utilies required
// for users to create an 'order' meaning they have requested
// delegations for a certian 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
}
|