haveapi-go-client 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/Gemfile +4 -0
  4. data/README.md +64 -0
  5. data/bin/haveapi-go-client +3 -0
  6. data/haveapi-go-client.gemspec +25 -0
  7. data/lib/haveapi/go_client/action.rb +128 -0
  8. data/lib/haveapi/go_client/api_version.rb +21 -0
  9. data/lib/haveapi/go_client/authentication/base.rb +13 -0
  10. data/lib/haveapi/go_client/authentication/basic.rb +21 -0
  11. data/lib/haveapi/go_client/authentication/token.rb +56 -0
  12. data/lib/haveapi/go_client/authentication/unsupported.rb +13 -0
  13. data/lib/haveapi/go_client/authentication_methods.rb +24 -0
  14. data/lib/haveapi/go_client/cli.rb +39 -0
  15. data/lib/haveapi/go_client/erb_template.rb +46 -0
  16. data/lib/haveapi/go_client/generator.rb +65 -0
  17. data/lib/haveapi/go_client/input_output.rb +48 -0
  18. data/lib/haveapi/go_client/metadata.rb +63 -0
  19. data/lib/haveapi/go_client/parameter.rb +27 -0
  20. data/lib/haveapi/go_client/parameters/association.rb +54 -0
  21. data/lib/haveapi/go_client/parameters/base.rb +66 -0
  22. data/lib/haveapi/go_client/parameters/global_meta_includes.rb +17 -0
  23. data/lib/haveapi/go_client/parameters/resource.rb +20 -0
  24. data/lib/haveapi/go_client/parameters/typed.rb +30 -0
  25. data/lib/haveapi/go_client/resource.rb +133 -0
  26. data/lib/haveapi/go_client/utils.rb +10 -0
  27. data/lib/haveapi/go_client/version.rb +5 -0
  28. data/lib/haveapi/go_client.rb +21 -0
  29. data/shell.nix +23 -0
  30. data/template/action.go.erb +475 -0
  31. data/template/authentication/basic.go.erb +22 -0
  32. data/template/authentication/token.go.erb +164 -0
  33. data/template/authentication.go.erb +10 -0
  34. data/template/client.go.erb +26 -0
  35. data/template/go.mod.erb +1 -0
  36. data/template/request.go.erb +96 -0
  37. data/template/resource.go.erb +36 -0
  38. data/template/response.go.erb +13 -0
  39. data/template/types.go.erb +41 -0
  40. metadata +125 -0
@@ -0,0 +1,475 @@
1
+ package <%= package %>
2
+
3
+ import (
4
+ <% if action.has_path_params? -%>
5
+ "strings"
6
+ <% end -%>
7
+ )
8
+
9
+ // <%= action.go_type %> is a type for action <%= action.full_dot_name %>
10
+ type <%= action.go_type %> struct {
11
+ // Pointer to client
12
+ Client *Client
13
+ }
14
+
15
+ func New<%= action.go_type %>(client *Client) *<%= action.go_type %> {
16
+ return &<%= action.go_type %>{
17
+ Client: client,
18
+ }
19
+ }
20
+
21
+ <% if action.metadata.has_global_input? -%>
22
+ // <%= action.metadata.global.input.go_type %> is a type for action global meta input parameters
23
+ type <%= action.metadata.global.input.go_type %> struct {
24
+ <% action.metadata.global.input.parameters.each do |p| -%>
25
+ <%= p.go_name %> <%= p.go_in_type %> `json:"<%= p.name %>"`
26
+ <% end -%>
27
+ // Only selected parameters are sent to the API. Ignored if empty.
28
+ _selectedParameters map[string]interface{}
29
+ }
30
+
31
+ <% action.metadata.global.input.parameters.each do |p| -%>
32
+ // Set<%= p.go_name %> sets parameter <%= p.go_name %> to value and selects it for sending
33
+ func (in *<%= action.metadata.global.input.go_type %>) Set<%= p.go_name %>(value <%= p.go_in_type %>) *<%= action.metadata.global.input.go_type %> {
34
+ in.<%= p.go_name %> = value
35
+
36
+ if in._selectedParameters == nil {
37
+ in._selectedParameters = make(map[string]interface{})
38
+ }
39
+
40
+ in._selectedParameters["<%= p.go_name %>"] = nil
41
+ return in
42
+ }
43
+ <% end -%>
44
+
45
+ // SelectParameters sets parameters from <%= action.metadata.global.input.go_type %>
46
+ // that will be sent to the API.
47
+ // SelectParameters can be called multiple times.
48
+ func (in *<%= action.metadata.global.input.go_type %>) SelectParameters(params ...string) *<%= action.metadata.global.input.go_type %> {
49
+ if in._selectedParameters == nil {
50
+ in._selectedParameters = make(map[string]interface{})
51
+ }
52
+
53
+ for _, param := range params {
54
+ in._selectedParameters[param] = nil
55
+ }
56
+
57
+ return in
58
+ }
59
+
60
+ func (in *<%= action.metadata.global.input.go_type %>) AnySelected() bool {
61
+ if in._selectedParameters == nil {
62
+ return false
63
+ }
64
+
65
+ return len(in._selectedParameters) > 0
66
+ }
67
+ <% end -%>
68
+
69
+ <% if action.has_input? -%>
70
+ // <%= action.input.go_type %> is a type for action input parameters
71
+ type <%= action.input.go_type %> struct {
72
+ <% action.input.parameters.each do |p| -%>
73
+ <%= p.go_name %> <%= p.go_in_type %> `json:"<%= p.name %>"`
74
+ <% end -%>
75
+ // Only selected parameters are sent to the API. Ignored if empty.
76
+ _selectedParameters map[string]interface{}
77
+ }
78
+
79
+ <% action.input.parameters.each do |p| -%>
80
+ // Set<%= p.go_name %> sets parameter <%= p.go_name %> to value and selects it for sending
81
+ func (in *<%= action.input.go_type %>) Set<%= p.go_name %>(value <%= p.go_in_type %>) *<%= action.input.go_type %> {
82
+ in.<%= p.go_name %> = value
83
+
84
+ if in._selectedParameters == nil {
85
+ in._selectedParameters = make(map[string]interface{})
86
+ }
87
+
88
+ in._selectedParameters["<%= p.go_name %>"] = nil
89
+ return in
90
+ }
91
+ <% end -%>
92
+
93
+ // SelectParameters sets parameters from <%= action.input.go_type %>
94
+ // that will be sent to the API.
95
+ // SelectParameters can be called multiple times.
96
+ func (in *<%= action.input.go_type %>) SelectParameters(params ...string) *<%= action.input.go_type %> {
97
+ if in._selectedParameters == nil {
98
+ in._selectedParameters = make(map[string]interface{})
99
+ }
100
+
101
+ for _, param := range params {
102
+ in._selectedParameters[param] = nil
103
+ }
104
+
105
+ return in
106
+ }
107
+
108
+ func (in *<%= action.input.go_type %>) AnySelected() bool {
109
+ if in._selectedParameters == nil {
110
+ return false
111
+ }
112
+
113
+ return len(in._selectedParameters) > 0
114
+ }
115
+ <% end -%>
116
+
117
+ <% if (action.has_input? || action.metadata.has_global_input?) && action.http_method != 'GET' -%>
118
+ // <%= action.go_request_type %> is a type for the entire action request
119
+ type <%= action.go_request_type %> struct {
120
+ <% if action.has_input? -%>
121
+ <%= action.input.go_namespace %> map[string]interface{} `json:"<%= action.input.namespace %>"`
122
+ <% end -%>
123
+ <% if action.metadata.has_global_input? -%>
124
+ Meta map[string]interface{} `json:"<%= action.resource.api_version.metadata_namespace %>"`
125
+ <% end -%>
126
+ }
127
+ <% end -%>
128
+
129
+ <% if action.has_output? -%>
130
+ // <%= action.output.go_type %> is a type for action output parameters
131
+ type <%= action.output.go_type %> struct {
132
+ <% action.output.parameters.each do |p| -%>
133
+ <% if p.respond_to?(:association) -%>
134
+ <%= p.go_name %> *<%= p.go_out_type %> `json:"<%= p.name %>"`
135
+ <% else -%>
136
+ <%= p.go_name %> <%= p.go_out_type %> `json:"<%= p.name %>"`
137
+ <% end -%>
138
+ <% end -%>
139
+ }
140
+ <% end -%>
141
+
142
+ <% if action.blocking? -%>
143
+ // <%= action.metadata.global.output.go_type %> is a type for global output metadata parameters
144
+ type <%= action.metadata.global.output.go_type %> struct {
145
+ <% action.metadata.global.output.parameters.each do |p| -%>
146
+ <%= p.go_name %> <%= p.go_out_type %> `json:"<%= p.name %>"`
147
+ <% end -%>
148
+ }
149
+ <% end -%>
150
+
151
+ // Type for action response, including envelope
152
+ type <%= action.go_response_type %> struct {
153
+ Action *<%= action.go_type %> `json:"-"`
154
+ *Envelope
155
+ <% if action.has_output? -%>
156
+ <% if %w(hash object).include?(action.output.layout) -%>
157
+ // Action output encapsulated within a namespace
158
+ Response *struct {
159
+ <%= action.output.go_namespace %> *<%= action.output.go_type %> `json:"<%= action.output.namespace %>"`
160
+ <% if action.blocking? -%>
161
+ // Global output metadata
162
+ Meta *<%= action.metadata.global.output.go_type %> `json:"<%= action.resource.api_version.metadata_namespace %>"`
163
+ <% end -%>
164
+ }
165
+
166
+ // Action output without the namespace
167
+ Output *<%= action.output.go_type %>
168
+ <% elsif %w(hash_list object_list).include?(action.output.layout) -%>
169
+ // Action output encapsulated within a namespace
170
+ Response *struct {
171
+ <%= action.output.go_namespace %> []*<%= action.output.go_type %> `json:"<%= action.output.namespace %>"`
172
+ <% if action.blocking? -%>
173
+ // Global output metadata
174
+ Meta *<%= action.metadata.global.output.go_type %> `json:"<%= action.resource.api_version.metadata_namespace %>"`
175
+ <% end -%>
176
+ }
177
+
178
+ // Action output without the namespace
179
+ Output []*<%= action.output.go_type %>
180
+ <% end -%>
181
+ <% elsif action.blocking? -%>
182
+ // Action output encapsulated within a namespace
183
+ Response *struct {
184
+ // Global output metadata
185
+ Meta *<%= action.metadata.global.output.go_type %> `json:"<%= action.resource.api_version.metadata_namespace %>"`
186
+ }
187
+ <% end -%>
188
+ }
189
+
190
+ <% if !action.has_path_params? && !action.has_input? -%>
191
+ // Call the action directly without any path or input parameters
192
+ func (action *<%= action.go_type %>) Call() (*<%= action.go_response_type %>, error) {
193
+ return action.Prepare().Call()
194
+ }
195
+ <% end -%>
196
+
197
+ // Prepare the action for invocation
198
+ func (action *<%= action.go_type %>) Prepare() *<%= action.go_invocation_type%> {
199
+ return &<%= action.go_invocation_type %>{
200
+ Action: action,
201
+ Path: "<%= action.path %>",
202
+ }
203
+ }
204
+
205
+ // <%= action.go_invocation_type %> is used to configure action for invocation
206
+ type <%= action.go_invocation_type %> struct {
207
+ // Pointer to the action
208
+ Action *<%= action.go_type %>
209
+
210
+ // Path which may contain parameters that need to be set
211
+ Path string
212
+ <% if action.has_input? -%>
213
+ // Input parameters
214
+ Input *<%= action.input.go_type %>
215
+ <% end -%>
216
+ <% if action.metadata.has_global_input? -%>
217
+ // Global meta input parameters
218
+ MetaInput *<%= action.metadata.global.input.go_type %>
219
+ <% end -%>
220
+ }
221
+
222
+ <% if action.has_path_params? -%>
223
+ // SetPathParamInt sets integer path parameter
224
+ func (inv *<%= action.go_invocation_type %>) SetPathParamInt(param string, value int64) *<%= action.go_invocation_type %> {
225
+ return inv.SetPathParamString(param, convertInt64ToString(value))
226
+ }
227
+
228
+ // SetPathParamString sets string path parameter
229
+ func (inv *<%= action.go_invocation_type %>) SetPathParamString(param string, value string) *<%= action.go_invocation_type %> {
230
+ inv.Path = strings.Replace(inv.Path, "{"+param+"}", value, 1)
231
+ return inv
232
+ }
233
+ <% end -%>
234
+
235
+ <% if action.has_input? -%>
236
+ // NewInput returns a new struct for input parameters and sets it as with SetInput
237
+ func (inv *<%= action.go_invocation_type %>) NewInput() *<%= action.input.go_type %> {
238
+ inv.Input = &<%= action.input.go_type %>{}
239
+ return inv.Input
240
+ }
241
+
242
+ // SetInput provides input parameters to send to the API
243
+ func (inv *<%= action.go_invocation_type %>) SetInput(input *<%= action.input.go_type %>) *<%= action.go_invocation_type %> {
244
+ inv.Input = input
245
+ return inv
246
+ }
247
+
248
+ // IsParameterSelected returns true if param is to be sent to the API
249
+ func (inv *<%= action.go_invocation_type %>) IsParameterSelected(param string) bool {
250
+ if inv.Input._selectedParameters == nil {
251
+ return true
252
+ }
253
+
254
+ _, exists := inv.Input._selectedParameters[param]
255
+ return exists
256
+ }
257
+ <% end -%>
258
+ <% if action.metadata.has_global_input? -%>
259
+ // NewMetaInput returns a new struct for global meta input parameters and sets
260
+ // it as with SetMetaInput
261
+ func (inv *<%= action.go_invocation_type %>) NewMetaInput() *<%= action.metadata.global.input.go_type %> {
262
+ inv.MetaInput = &<%= action.metadata.global.input.go_type %>{}
263
+ return inv.MetaInput
264
+ }
265
+
266
+ // SetMetaInput provides global meta input parameters to send to the API
267
+ func (inv *<%= action.go_invocation_type %>) SetMetaInput(input *<%= action.metadata.global.input.go_type %>) *<%= action.go_invocation_type %> {
268
+ inv.MetaInput = input
269
+ return inv
270
+ }
271
+
272
+ // IsMetaParameterSelected returns true if global meta param is to be sent to the API
273
+ func (inv *<%= action.go_invocation_type %>) IsMetaParameterSelected(param string) bool {
274
+ if inv.MetaInput._selectedParameters == nil {
275
+ return true
276
+ }
277
+
278
+ _, exists := inv.MetaInput._selectedParameters[param]
279
+ return exists
280
+ }
281
+ <% end -%>
282
+
283
+ // Call() invokes the action and returns a response from the API server
284
+ func (inv *<%= action.go_invocation_type %>) Call() (*<%= action.go_response_type %>, error) {
285
+ <% if action.http_method == 'GET' -%>
286
+ return inv.callAsQuery()
287
+ <% else -%>
288
+ return inv.callAsBody()
289
+ <% end -%>
290
+ }
291
+
292
+ <% if action.http_method == 'GET' -%>
293
+ func (inv *<%= action.go_invocation_type %>) callAsQuery() (*<%= action.go_response_type %>, error) {
294
+ queryParams := make(map[string]string)
295
+ <% if action.has_input? -%>
296
+ inv.convertInputToQueryParams(queryParams)
297
+ <% end -%>
298
+ <% if action.metadata.has_global_input? -%>
299
+ inv.convertMetaInputToQueryParams(queryParams)
300
+ <% end -%>
301
+ resp := &<%= action.go_response_type %>{Action: inv.Action}
302
+ err := inv.Action.Client.DoQueryStringRequest(inv.Path, queryParams, resp)
303
+ <% if action.has_output? -%>
304
+ if err == nil && resp.Status {
305
+ resp.Output = resp.Response.<%= action.output.go_namespace %>
306
+ }
307
+ <% end -%>
308
+ return resp, err
309
+ }
310
+ <% end -%>
311
+
312
+ <% if action.http_method != 'GET' -%>
313
+ func (inv *<%= action.go_invocation_type %>) callAsBody() (*<%= action.go_response_type %>, error) {
314
+ <% if action.has_input? || action.metadata.has_global_input? -%>
315
+ input := inv.makeAllInputParams()
316
+ <% else -%>
317
+ input := make(map[string]interface{})
318
+ <% end -%>
319
+ resp := &<%= action.go_response_type %>{Action: inv.Action}
320
+ err := inv.Action.Client.DoBodyRequest("<%= action.http_method %>", inv.Path, input, resp)
321
+ <% if action.has_output? -%>
322
+ if err == nil && resp.Status {
323
+ resp.Output = resp.Response.<%= action.output.go_namespace %>
324
+ }
325
+ <% end -%>
326
+ return resp, err
327
+ }
328
+ <% end -%>
329
+
330
+ <% if action.blocking? -%>
331
+ // IsBlocking checks whether the current invocation resulted in a blocking operation
332
+ func (resp *<%= action.go_response_type %>) IsBlocking() bool {
333
+ return resp.Response.Meta != nil && resp.Response.Meta.ActionStateId > 0
334
+ }
335
+
336
+ // OperationStatus queries the current state of the blocking operation
337
+ func (resp *<%= action.go_response_type %>) OperationStatus() (*ActionActionStateShowResponse, error) {
338
+ req := resp.Action.Client.ActionState.Show.Prepare()
339
+ req.SetPathParamInt("action_state_id", resp.Response.Meta.ActionStateId)
340
+ return req.Call()
341
+ }
342
+
343
+ // WaitForOperation waits for a blocking operation to finish
344
+ func (resp *<%= action.go_response_type %>) WaitForOperation(timeout float64) (*ActionActionStatePollResponse, error) {
345
+ req := resp.Action.Client.ActionState.Poll.Prepare()
346
+ req.SetPathParamInt("action_state_id", resp.Response.Meta.ActionStateId)
347
+
348
+ input := req.NewInput()
349
+ input.SetTimeout(timeout)
350
+
351
+ return req.Call()
352
+ }
353
+
354
+ // WatchOperation waits for a blocking operation to finish and calls a callback
355
+ // function with progress updates
356
+ func (resp *<%= action.go_response_type %>) WatchOperation(timeout float64, updateIn float64, callback OperationProgressCallback) (*ActionActionStatePollResponse, error) {
357
+ req := resp.Action.Client.ActionState.Poll.Prepare()
358
+ req.SetPathParamInt("action_state_id", resp.Response.Meta.ActionStateId)
359
+
360
+ input := req.NewInput()
361
+ input.SetTimeout(timeout)
362
+ input.SetUpdateIn(updateIn)
363
+
364
+ pollResp, err := req.Call()
365
+
366
+ if err != nil {
367
+ return pollResp, err
368
+ } else if pollResp.Output.Finished {
369
+ return pollResp, nil
370
+ }
371
+
372
+ if callback(pollResp.Output) == StopWatching {
373
+ return pollResp, nil
374
+ }
375
+
376
+ for {
377
+ req = resp.Action.Client.ActionState.Poll.Prepare()
378
+ req.SetPathParamInt("action_state_id", resp.Response.Meta.ActionStateId)
379
+ req.SetInput(&ActionActionStatePollInput{
380
+ Timeout: timeout,
381
+ UpdateIn: updateIn,
382
+ Status: pollResp.Output.Status,
383
+ Current: pollResp.Output.Current,
384
+ Total: pollResp.Output.Total,
385
+ })
386
+ pollResp, err = req.Call()
387
+
388
+ if err != nil {
389
+ return pollResp, err
390
+ } else if pollResp.Output.Finished {
391
+ return pollResp, nil
392
+ }
393
+
394
+ if callback(pollResp.Output) == StopWatching {
395
+ return pollResp, nil
396
+ }
397
+ }
398
+ }
399
+
400
+ // CancelOperation cancels the current blocking operation
401
+ func (resp *<%= action.go_response_type %>) CancelOperation() (*ActionActionStateCancelResponse, error) {
402
+ req := resp.Action.Client.ActionState.Cancel.Prepare()
403
+ req.SetPathParamInt("action_state_id", resp.Response.Meta.ActionStateId)
404
+ return req.Call()
405
+ }
406
+ <% end -%>
407
+
408
+ <% if action.http_method == 'GET' && action.has_input? -%>
409
+ func (inv *<%= action.go_invocation_type %>) convertInputToQueryParams(ret map[string]string) {
410
+ if inv.Input != nil {
411
+ <% action.input.parameters.each do |p| -%>
412
+ if inv.IsParameterSelected("<%= p.go_name %>") {
413
+ ret["<%= action.input.namespace %>[<%= p.name %>]"] = <% if p.go_in_type == 'string' %>inv.Input.<%= p.go_name %><% else %>convert<%= p.go_in_type.capitalize %>ToString(inv.Input.<%= p.go_name %>)<% end %>
414
+ }
415
+ <% end -%>
416
+ }
417
+ }
418
+ <% end -%>
419
+
420
+ <% if action.http_method == 'GET' && action.metadata.has_global_input? -%>
421
+ func (inv *<%= action.go_invocation_type %>) convertMetaInputToQueryParams(ret map[string]string) {
422
+ if inv.MetaInput != nil {
423
+ <% action.metadata.global.input.parameters.each do |p| -%>
424
+ if inv.IsMetaParameterSelected("<%= p.go_name %>") {
425
+ ret["<%= action.resource.api_version.metadata_namespace %>[<%= p.name %>]"] = <% if p.go_in_type == 'string' %>inv.MetaInput.<%= p.go_name %><% else %>convert<%= p.go_in_type.capitalize %>ToString(inv.MetaInput.<%= p.go_name %>)<% end %>
426
+ }
427
+ <% end -%>
428
+ }
429
+ }
430
+ <% end -%>
431
+
432
+ <% if action.http_method != 'GET' && (action.has_input? || action.metadata.has_global_input?) -%>
433
+ func (inv *<%= action.go_invocation_type %>) makeAllInputParams() *<%= action.go_request_type %> {
434
+ return &<%= action.go_request_type %>{
435
+ <% if action.has_input? -%>
436
+ <%= action.input.go_namespace %>: inv.makeInputParams(),
437
+ <% end -%>
438
+ <% if action.metadata.has_global_input? -%>
439
+ Meta: inv.makeMetaInputParams(),
440
+ <% end -%>
441
+ }
442
+ }
443
+
444
+ <% if action.has_input? -%>
445
+ func (inv *<%= action.go_invocation_type %>) makeInputParams() map[string]interface{} {
446
+ ret := make(map[string]interface{})
447
+
448
+ if inv.Input != nil {
449
+ <% action.input.parameters.each do |p| -%>
450
+ if inv.IsParameterSelected("<%= p.go_name %>") {
451
+ ret["<%= p.name %>"] = inv.Input.<%= p.go_name %>
452
+ }
453
+ <% end -%>
454
+ }
455
+
456
+ return ret
457
+ }
458
+ <% end -%>
459
+
460
+ <% if action.metadata.has_global_input? -%>
461
+ func (inv *<%= action.go_invocation_type %>) makeMetaInputParams() map[string]interface{} {
462
+ ret := make(map[string]interface{})
463
+
464
+ if inv.MetaInput != nil {
465
+ <% action.metadata.global.input.parameters.each do |p| -%>
466
+ if inv.IsMetaParameterSelected("<%= p.go_name %>") {
467
+ ret["<%= p.name %>"] = inv.MetaInput.<%= p.go_name %>
468
+ }
469
+ <% end -%>
470
+ }
471
+
472
+ return ret
473
+ }
474
+ <% end -%>
475
+ <% end -%>
@@ -0,0 +1,22 @@
1
+ package <%= package %>
2
+
3
+ import (
4
+ "net/http"
5
+ )
6
+
7
+ type BasicAuth struct {
8
+ Username string
9
+ Password string
10
+ }
11
+
12
+ func (auth *BasicAuth) Authenticate(request *http.Request) {
13
+ request.SetBasicAuth(auth.Username, auth.Password)
14
+ }
15
+
16
+ // SetBasicAuthentication enables HTTP basic auth on the client
17
+ func (client *Client) SetBasicAuthentication(username string, password string) {
18
+ client.Authentication = &BasicAuth{
19
+ Username: username,
20
+ Password: password,
21
+ }
22
+ }
@@ -0,0 +1,164 @@
1
+ package <%= package %>
2
+
3
+ import (
4
+ "fmt"
5
+ "net/http"
6
+ )
7
+
8
+ type Mode int
9
+
10
+ const (
11
+ // Send the token via HTTP header <%= auth.http_header %>
12
+ HttpHeader Mode = iota
13
+
14
+ // Send the token via query parameter <%= auth.query_parameter %>
15
+ QueryParameter = iota
16
+ )
17
+
18
+ type TokenAuth struct {
19
+ // Resource for token manipulation
20
+ Resource *AuthTokenResourceToken
21
+
22
+ // The authentication token
23
+ Token string
24
+
25
+ // Mode determines how is the authentication token sent to the API
26
+ Mode Mode
27
+ }
28
+
29
+ func (auth *TokenAuth) Authenticate(request *http.Request) {
30
+ switch auth.Mode {
31
+ case HttpHeader:
32
+ request.Header.Set("<%= auth.http_header %>", auth.Token)
33
+
34
+ case QueryParameter:
35
+ q := request.URL.Query()
36
+ q.Add("<%= auth.query_parameter %>", auth.Token)
37
+ request.URL.RawQuery = q.Encode()
38
+ }
39
+ }
40
+
41
+ type TokenAuthOptions struct {
42
+ <% auth.request_action.input.parameters.each do |p| -%>
43
+ <%= p.go_name %> <%= p.go_in_type %>
44
+ <% end -%>
45
+ <% auth.custom_actions.each do |a| -%>
46
+ <%= "#{a.go_name}Callback" %> func(input *<%= a.input.go_type %>) error
47
+ <% end -%>
48
+ }
49
+
50
+ // SetNewTokenAuth obtains a new authentication token with login credentials
51
+ func (client *Client) SetNewTokenAuth(options *TokenAuthOptions) error {
52
+ resource := NewAuthTokenResourceToken(client)
53
+ auth := &TokenAuth{Resource: resource, Mode: HttpHeader}
54
+ auth.setDefaultOptions(options)
55
+
56
+ request := resource.Request.Prepare()
57
+ request.SetInput(&AuthTokenActionTokenRequestInput{
58
+ <% auth.request_action.input.parameters.each do |p| -%>
59
+ <%= p.go_name %>: options.<%= p.go_name %>,
60
+ <% end -%>
61
+ })
62
+
63
+ resp, err := request.Call()
64
+
65
+ if err != nil {
66
+ return err
67
+ } else if !resp.Status {
68
+ return fmt.Errorf("Unable to request token: %v", resp.Message)
69
+ }
70
+
71
+ if resp.Output.Complete {
72
+ auth.Token = resp.Output.Token
73
+ client.Authentication = auth
74
+ return nil
75
+ }
76
+
77
+ return auth.nextAuthenticationStep(
78
+ options,
79
+ resp.Output.NextAction,
80
+ resp.Output.Token,
81
+ );
82
+ }
83
+
84
+ func (auth *TokenAuth) setDefaultOptions(options *TokenAuthOptions) {
85
+ if options.Lifetime == "" {
86
+ options.Lifetime = "renewable_auto"
87
+ }
88
+
89
+ if options.Interval == 0 {
90
+ options.Interval = 300
91
+ }
92
+ }
93
+
94
+ // nextAuthenticationStep performs authentication steps recursively, until
95
+ // the authentication is completed
96
+ func (auth *TokenAuth) nextAuthenticationStep(options *TokenAuthOptions, action string, token string) error {
97
+ <% auth.custom_actions.each do |a| -%>
98
+ if action == "<%= a.name %>" {
99
+ action := auth.Resource.<%= a.go_name %>.Prepare()
100
+ input := action.NewInput()
101
+ input.SetToken(token)
102
+
103
+ if options.<%= "#{a.go_name}Callback" %> == nil {
104
+ return fmt.Errorf("Implement callback <%= "#{a.go_name}Callback" %>")
105
+ }
106
+
107
+ if err := options.<%= "#{a.go_name}Callback" %>(input); err != nil {
108
+ return fmt.Errorf("<%= "#{a.go_name}Callback" %> failed: %v", err)
109
+ }
110
+
111
+ resp, err := action.Call()
112
+
113
+ if err != nil {
114
+ return err
115
+ } else if !resp.Status {
116
+ return fmt.Errorf("Failed at authentication step '%s': %v", action, resp.Message)
117
+ }
118
+
119
+ if resp.Output.Complete {
120
+ auth.Token = resp.Output.Token
121
+ auth.Resource.Client.Authentication = auth
122
+ return nil
123
+ }
124
+
125
+ return auth.nextAuthenticationStep(
126
+ options,
127
+ resp.Output.NextAction,
128
+ resp.Output.Token,
129
+ );
130
+ }
131
+ <% end -%>
132
+
133
+ return fmt.Errorf("Unsupported authentication action '%s'", action)
134
+ }
135
+
136
+ // SetExistingTokenAuth will use a previously acquired token
137
+ func (client *Client) SetExistingTokenAuth(token string) {
138
+ client.Authentication = &TokenAuth{
139
+ Resource: NewAuthTokenResourceToken(client),
140
+ Token: token,
141
+ Mode: HttpHeader,
142
+ }
143
+ }
144
+
145
+ // SetTokenAuthMode can be used to change the way the token is sent to the API
146
+ func (client *Client) SetTokenAuthMode(mode Mode) {
147
+ client.Authentication.(*TokenAuth).Mode = mode
148
+ }
149
+
150
+ // RevokeAuthToken will revoke the authentication token and remove authentication
151
+ // from the client
152
+ func (client *Client) RevokeAuthToken() error {
153
+ revoke := client.Authentication.(*TokenAuth).Resource.Revoke.Prepare()
154
+ resp, err := revoke.Call()
155
+
156
+ if err != nil {
157
+ return err
158
+ } else if !resp.Status {
159
+ return fmt.Errorf("Unable to revoke token: %v", resp.Message)
160
+ }
161
+
162
+ client.Authentication = nil
163
+ return nil
164
+ }
@@ -0,0 +1,10 @@
1
+ package <%= package %>
2
+
3
+ import (
4
+ "net/http"
5
+ )
6
+
7
+ // Authenticator is used to provide authentication for HTTP requests
8
+ type Authenticator interface {
9
+ Authenticate(request *http.Request)
10
+ }
@@ -0,0 +1,26 @@
1
+ package <%= package %>
2
+
3
+ // Client represents a connection to an API server
4
+ type Client struct {
5
+ // API URL
6
+ Url string
7
+
8
+ // Options for authentication method
9
+ Authentication Authenticator
10
+
11
+ <% api.resources.each do |r| -%>
12
+ // Resource <%= r.full_dot_name %>
13
+ <%= r.go_name %> *<%= r.go_type %>
14
+ <% end -%>
15
+ }
16
+
17
+ // Create a new client for API at url
18
+ func New(url string) *Client {
19
+ c := &Client{Url: url}
20
+
21
+ <% api.resources.each do |r| -%>
22
+ c.<%= r.go_name %> = New<%= r.go_type %>(c)
23
+ <% end -%>
24
+
25
+ return c
26
+ }
@@ -0,0 +1 @@
1
+ module <%= mod %>