/
bosh.go
132 lines (106 loc) · 3.44 KB
/
bosh.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package bosh
import (
"github.com/cloudfoundry/bosh-cli/director"
"github.com/evoila/infraTESTure/infrastructure"
"log"
"math"
"strings"
)
// Return a map of all IPs of the deployment with the VM ID as the key, and all affiliated IPs as the value
// @return map Map containing all IPs of the deployment
func (b *Bosh) GetIPs() map[string][]string {
// Get the ips of all VMs of a deployment
vmInfos, err := deployment.VMInfos()
if err != nil {
logError(err, "")
}
ips := make(map[string][]string)
for _, vmInfo := range vmInfos {
for _, ip := range vmInfo.IPs {
ips[vmInfo.ID] = append(ips[vmInfo.ID], ip)
}
}
return ips
}
// Return an own Deployment struct with some important metrics
// @return deployment Initialized deployment struct from github.com/evoila/infraTESTure/infrastructure
func (b *Bosh) GetDeployment() infrastructure.Deployment {
vmVitals, err := deployment.VMInfos()
if err != nil {
log.Printf("[ERROR] %v", err)
}
var vms []infrastructure.VM
for _, vmVital := range vmVitals {
used, available := ParseDiskSize(vmVital.ID)
vms = append(vms, infrastructure.VM{
ServiceName: vmVital.JobName,
ID: vmVital.ID,
IPs: vmVital.IPs,
State: vmVital.ProcessState,
CpuUsage: math.Round(stringToFloat(vmVital.Vitals.CPU.User) + stringToFloat(vmVital.Vitals.CPU.Sys)),
MemoryUsagePercentage: stringToFloat(vmVital.Vitals.Mem.Percent),
MemoryUsageTotal: stringToFloat(vmVital.Vitals.Mem.KB),
DiskSize: stringToFloat(used) + stringToFloat(available),
DiskUsageTotal: stringToFloat(used),
DiskUsagePercentage: stringToFloat(vmVital.Vitals.Disk["persistent"].Percent),
})
}
return infrastructure.Deployment{
DeploymentName: deploymentName,
Hosts: b.GetIPs(),
VMs: vms,
}
}
// Check if a VM is running
// @return bool Bool value telling if the VM is running (true) or not (false)
func (b *Bosh) IsRunning() bool {
vmVitals, err := deployment.VMInfos()
if err != nil {
log.Printf("[ERROR] %v\n", err)
}
for _, vmVital := range vmVitals {
if vmVital.ProcessState != "running" {
return false
}
}
return true
}
// Stop a VM based on the VM ID
// @param id Id of the VM you want to stop
func (b *Bosh) Stop(id string) {
err := deployment.Stop(director.NewAllOrInstanceGroupOrInstanceSlug("", id), director.StopOpts{
Converge: true,
})
if err != nil {
logError(err, "")
}
}
// Start a VM based on the VM ID
// @param id Id of the VM you want to start
func (b *Bosh) Start(id string) {
// Restart a stopped VM
err := deployment.Start(director.NewAllOrInstanceGroupOrInstanceSlug("", id), director.StartOpts{
Converge: true,
})
if err != nil {
logError(err, "")
}
}
// SSH to vm and run df command in order to get the free disk space then filter the one needed
// @param vmId Id of the VM you want to determine used and available disk space from
// @return used Value in bytes of used disk space
// @return available Value in bytes of available disk space
func ParseDiskSize(vmId string) (used string, available string){
result, err := RunSshCommand(vmId, "df | awk 'NR > 1{print $6\" \"$3\" \"$4 }'")
if err != nil {
logError(err, "Failed to acquire disk size information")
}
fields := strings.Fields(result)
for i, field := range fields {
//TODO: Hardcoded or configurable?
if strings.HasPrefix(field, "/var/vcap/store") {
return fields[i+1], fields[i+2]
}
}
return "", ""
}