This repository has been archived by the owner on Oct 20, 2023. It is now read-only.
/
bosh_metadata.go
83 lines (71 loc) · 2.52 KB
/
bosh_metadata.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
package metrics
import (
"log"
"time"
//"github.com/davecgh/go-spew/spew"
)
type BoshMetadataFetcher struct {
client *BoshClient
vmCache map[string]*BoshVM
// deployment name -> time last updated
vmCacheLastUpdate map[string]time.Time
CacheExpirySeconds int
// Golang's version of a set
vmsNotFound map[string]bool
}
const defaultBoshCacheExpirySeconds = 180
func NewBoshMetadataFetcher(boshClient *BoshClient) *BoshMetadataFetcher {
return &BoshMetadataFetcher{
client: boshClient,
vmCache: make(map[string]*BoshVM),
vmCacheLastUpdate: make(map[string]time.Time),
CacheExpirySeconds: defaultBoshCacheExpirySeconds,
vmsNotFound: make(map[string]bool),
}
}
// This just returns the first ip address given by BOSH
func (o *BoshMetadataFetcher) GetVMIPAddress(deploymentName, vmId string) string {
vm := o.getVM(deploymentName, vmId)
if vm == nil || len(vm.Ips) == 0 {
return ""
}
return vm.Ips[0]
}
func (o *BoshMetadataFetcher) refreshVMCacheFor(deploymentName string) {
log.Print("Refreshing BOSH VM cache for ", deploymentName)
vms := o.client.fetchVMs(deploymentName)
// Use index since the value will be a copy of the pointed value and not
// the value via the original pointer
for i := range vms {
o.vmCache[vms[i].Id] = &vms[i]
}
o.vmCacheLastUpdate[deploymentName] = time.Now()
}
func (o *BoshMetadataFetcher) getVM(deploymentName, vmId string) *BoshVM {
lastUpdate := o.vmCacheLastUpdate[deploymentName]
if lastUpdate.IsZero() {
o.refreshVMCacheFor(deploymentName)
} else {
expiryTime := lastUpdate.Add(time.Duration(o.CacheExpirySeconds) * time.Second)
if expiryTime.Before(time.Now()) {
log.Print("Expiring BOSH vm cache for deployment: ", deploymentName)
o.refreshVMCacheFor(deploymentName)
}
}
vm, ok := o.vmCache[vmId]
if !ok {
// Make sure we don't get into infinite recursion by only refetching
// for a vm once
if o.vmsNotFound[vmId] {
log.Printf("VM '%s' not found again, something is inconsistent.", vmId)
} else {
log.Printf("VM '%s' not found in cache, refetching...", vmId)
o.vmsNotFound[vmId] = true
o.refreshVMCacheFor(deploymentName)
return o.getVM(deploymentName, vmId)
}
} else {
delete(o.vmsNotFound, vmId)
}
return vm
}