-
Notifications
You must be signed in to change notification settings - Fork 1
/
virtualhost.go
112 lines (92 loc) · 2.91 KB
/
virtualhost.go
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
package main
import (
"errors"
"strings"
"sync"
"go.uber.org/zap"
"github.com/erikbos/gatekeeper/pkg/db"
"github.com/erikbos/gatekeeper/pkg/types"
)
type vhostMapping struct {
db *db.Database
vhostListeners map[vhostMapKey]vhostMapEntry
defaultOrganization string
logger *zap.Logger
}
type vhostMapKey struct {
vhost string
port int
}
type vhostMapEntry struct {
// Listener associated with this vhost
listener types.Listener
// Organization to use for lookups when request needs to be evaluated
organization types.Organization
}
func newVhostMapping(db *db.Database, defaultOrganization string, logger *zap.Logger) *vhostMapping {
return &vhostMapping{
db: db,
defaultOrganization: defaultOrganization,
logger: logger,
}
}
func newVhostMapKey(vhost string, port int) vhostMapKey {
return vhostMapKey{
vhost: strings.ToLower(vhost),
port: port,
}
}
// WaitFor updates the vhost to listener map after receiving a trigger that listeners in db have changed
func (v *vhostMapping) WaitFor(entityNotifications chan db.EntityChangeNotification) {
for changedEntity := range entityNotifications {
v.logger.Info("Database change notify received",
zap.String("entity", changedEntity.Resource))
if changedEntity.Resource == types.TypeListenerName ||
changedEntity.Resource == types.TypeRouteName {
v.buildVhostMap()
}
}
}
func (v *vhostMapping) buildVhostMap() {
listeners, err := v.db.Listener.GetAll()
if err != nil {
v.logger.Error("cannot retrieve listeners to build vhost map")
return
}
newVHostListeners := make(map[vhostMapKey]vhostMapEntry)
for _, listener := range listeners {
for _, host := range listener.VirtualHosts {
// Retrieve organization details, based upon Listernet attribute Organization, or use
// default organizationName from startup configuration
organization, err := v.db.Organization.Get(
listener.Attributes.GetAsString(types.AttributeOrganization, v.defaultOrganization))
if err != nil {
v.logger.Error("cannot retrieve organization details",
zap.String("listener", listener.Name))
continue
}
key := newVhostMapKey(host, listener.Port)
entry := vhostMapEntry{
listener: listener,
organization: *organization,
}
newVHostListeners[key] = entry
v.logger.Debug("vhostmap",
zap.String("host", key.vhost),
zap.Int("port", key.port),
zap.String("organization", entry.organization.Name))
}
}
var m sync.Mutex
m.Lock()
v.vhostListeners = newVHostListeners
m.Unlock()
}
// Lookup return listener and organization details based upon vhost and port
func (v *vhostMapping) Lookup(vhost string, port int) (*types.Listener, *types.Organization, error) {
vhostMapEntry, ok := v.vhostListeners[newVhostMapKey(vhost, port)]
if ok {
return &vhostMapEntry.listener, &vhostMapEntry.organization, nil
}
return nil, nil, errors.New("vhost not found")
}