-
Notifications
You must be signed in to change notification settings - Fork 1
/
client.go
180 lines (161 loc) · 5.25 KB
/
client.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
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
169
170
171
172
173
174
175
176
177
178
179
180
package lib
import (
auth3 "github.com/BytemarkHosting/auth-client"
"github.com/BytemarkHosting/bytemark-client/util/log"
)
// EndpointURLs are the URLs stored by the client for the various API endpoints the client touches.
// The key endpoints that you may wish to alter are Auth and Brain. When using an auth server and brain
// that doesn't have a matching bmbilling API, Billing should be set to ""
type EndpointURLs struct {
API string
Auth string
Billing string
Brain string
SPP string
}
// DefaultURLs returns an EndpointURLs for the usual customer-facing Bytemark APIs.
func DefaultURLs() EndpointURLs {
return EndpointURLs{
API: "https://api.bytemark.co.uk",
Auth: "https://auth.bytemark.co.uk",
Billing: "https://bmbilling.bytemark.co.uk",
Brain: "https://uk0.bigv.io",
SPP: "https://spp-submissions.bytemark.co.uk",
}
}
// Endpoint is an enum-style type to avoid people using endpoints like ints
type Endpoint int
const (
// AuthEndpoint means "make the connection to auth!"
AuthEndpoint Endpoint = iota
// BrainEndpoint means "make the connection to the brain!"
BrainEndpoint
// BillingEndpoint means "make the connection to bmbilling!"
BillingEndpoint
// SPPEndpoint means "make the connection to SPP!"
SPPEndpoint
// APIEndpoint means "make the connection to the general API endpoint!" (api.bytemark.co.uk - atm only used for domains?)
APIEndpoint
)
// bytemarkClient is the main type in the Bytemark API client library
type bytemarkClient struct {
allowInsecure bool
auth *auth3.Client
authSession *auth3.SessionData
debugLevel int
urls EndpointURLs
}
// New creates a new Bytemark API client using the default bytemark endpoints.
// This function will be renamed to New in 3.0
func New() (Client, error) {
return NewWithURLs(DefaultURLs())
}
// NewWithURLs creates a new Bytemark API client using the given endpoints.
func NewWithURLs(urls EndpointURLs) (c Client, err error) {
if urls.Auth == "" {
urls.Auth = "https://auth.bytemark.co.uk"
}
auth, err := auth3.New(urls.Auth)
if err != nil {
return nil, err
}
client := bytemarkClient{
urls: urls,
auth: auth,
debugLevel: 0,
}
return &client, nil
}
// GetEndpoint returns the Bytemark API endpoint currently in use.
func (c *bytemarkClient) GetEndpoint() string {
return c.urls.Brain
}
// GetBillingEndpoint returns the Bytemark Billing API endpoint in use.
// This function is deprecated and will be removed in a point release.
// DO NOT DEPEND ON IT
// TODO(telyn): remove this
func (c *bytemarkClient) GetBillingEndpoint() string {
return c.urls.Billing
}
// SetDebugLevel sets the debug level / verbosity of the Bytemark API client. 0 (default) is silent.
func (c *bytemarkClient) SetDebugLevel(debugLevel int) {
c.debugLevel = debugLevel
}
// GetSessionFactors returns the factors provided when the current auth session was set up
func (c *bytemarkClient) GetSessionFactors() []string {
if c.authSession == nil {
return []string{}
}
return c.authSession.Factors
}
// GetSessionToken returns the token for the current auth session
func (c *bytemarkClient) GetSessionToken() string {
if c.authSession == nil {
return ""
}
return c.authSession.Token
}
func (c *bytemarkClient) GetSessionUser() string {
if c.authSession == nil {
return ""
}
return c.authSession.Username
}
func (c *bytemarkClient) AllowInsecureRequests() {
c.allowInsecure = true
}
func (c *bytemarkClient) EnsureVirtualMachineName(vm *VirtualMachineName) error {
if vm.Account == "" {
if err := c.EnsureAccountName(&vm.Account); err != nil {
return err
}
}
if vm.Group == "" {
vm.Group = DefaultGroup
}
if vm.VirtualMachine == "" {
return BadNameError{Type: "virtual machine", ProblemField: "name", ProblemValue: vm.VirtualMachine}
}
return nil
}
func (c *bytemarkClient) EnsureGroupName(group *GroupName) error {
if group.Account == "" {
if err := c.EnsureAccountName(&group.Account); err != nil {
return err
}
}
if group.Group == "" {
group.Group = DefaultGroup
}
return nil
}
func (c *bytemarkClient) EnsureAccountName(account *string) error {
if *account == "" && c.authSession != nil {
log.Debug(log.LvlArgs, "validateAccountName called with empty name and a valid auth session - will try to figure out the default by talking to APIs.")
if c.urls.Billing == "" {
log.Debug(log.LvlArgs, "validateAccountName - there's no Billing endpoint, so we're most likely on a cluster devoid of bmbilling. Requesting account list from bigv...")
brainAccs, err := c.getBrainAccounts()
if err != nil {
return err
}
log.Debugf(log.LvlArgs, "validateAccountName found %d accounts\r\n", len(brainAccs))
if len(brainAccs) > 0 {
log.Debugf(log.LvlArgs, "validateAccountName using the first account returned from bigv (%s) as the default\r\n", brainAccs[0].Name)
*account = brainAccs[0].Name
}
} else {
log.Debug(log.LvlArgs, "validateAccountName finding the default billing account")
billAcc, err := c.getDefaultBillingAccount()
if err == nil && billAcc.IsValid() {
log.Debugf(log.LvlArgs, "validateAccountName found the default billing account - %s\r\n", billAcc.Name)
*account = billAcc.Name
} else if err != nil {
return err
}
}
}
if *account == "" {
return NoDefaultAccountError{}
}
return nil
}