haveapi-go-client 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
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 %>