scooter 0.0.0 → 3.2.19

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 (47) hide show
  1. checksums.yaml +15 -0
  2. data/.env +5 -0
  3. data/.gitignore +47 -19
  4. data/Gemfile +3 -0
  5. data/HISTORY.md +1539 -0
  6. data/README.md +69 -10
  7. data/Rakefile +7 -0
  8. data/docs/http_dispatchers.md +79 -0
  9. data/lib/scooter.rb +11 -3
  10. data/lib/scooter/httpdispatchers.rb +12 -0
  11. data/lib/scooter/httpdispatchers/activity.rb +46 -0
  12. data/lib/scooter/httpdispatchers/activity/v1/v1.rb +50 -0
  13. data/lib/scooter/httpdispatchers/classifier.rb +376 -0
  14. data/lib/scooter/httpdispatchers/classifier/v1/v1.rb +99 -0
  15. data/lib/scooter/httpdispatchers/code_manager.rb +31 -0
  16. data/lib/scooter/httpdispatchers/code_manager/v1/v1.rb +17 -0
  17. data/lib/scooter/httpdispatchers/consoledispatcher.rb +132 -0
  18. data/lib/scooter/httpdispatchers/httpdispatcher.rb +168 -0
  19. data/lib/scooter/httpdispatchers/orchestrator/v1/v1.rb +87 -0
  20. data/lib/scooter/httpdispatchers/orchestratordispatcher.rb +83 -0
  21. data/lib/scooter/httpdispatchers/puppetdb/v4/v4.rb +51 -0
  22. data/lib/scooter/httpdispatchers/puppetdbdispatcher.rb +390 -0
  23. data/lib/scooter/httpdispatchers/rbac.rb +231 -0
  24. data/lib/scooter/httpdispatchers/rbac/v1/directory_service.rb +68 -0
  25. data/lib/scooter/httpdispatchers/rbac/v1/v1.rb +116 -0
  26. data/lib/scooter/ldap.rb +349 -0
  27. data/lib/scooter/ldap/ldap_fixtures.rb +60 -0
  28. data/lib/scooter/middleware/rbac_auth_token.rb +35 -0
  29. data/lib/scooter/utilities.rb +9 -0
  30. data/lib/scooter/utilities/beaker_utilities.rb +41 -0
  31. data/lib/scooter/utilities/string_utilities.rb +32 -0
  32. data/lib/scooter/version.rb +3 -1
  33. data/scooter.gemspec +23 -6
  34. data/spec/scooter/beaker_utilities_spec.rb +53 -0
  35. data/spec/scooter/httpdispatchers/activity/activity_spec.rb +218 -0
  36. data/spec/scooter/httpdispatchers/classifier/classifier_spec.rb +542 -0
  37. data/spec/scooter/httpdispatchers/code_manager/code-manager_spec.rb +67 -0
  38. data/spec/scooter/httpdispatchers/consoledispatcher_spec.rb +80 -0
  39. data/spec/scooter/httpdispatchers/httpdispatcher_spec.rb +91 -0
  40. data/spec/scooter/httpdispatchers/middleware/rbac_auth_token_spec.rb +58 -0
  41. data/spec/scooter/httpdispatchers/orchestratordispatcher_spec.rb +195 -0
  42. data/spec/scooter/httpdispatchers/puppetdbdispatcher_spec.rb +246 -0
  43. data/spec/scooter/httpdispatchers/rbac/rbac_spec.rb +387 -0
  44. data/spec/scooter/string_utilities_spec.rb +83 -0
  45. data/spec/spec_helper.rb +8 -0
  46. metadata +270 -18
  47. data/LICENSE.txt +0 -15
@@ -0,0 +1,542 @@
1
+ require 'spec_helper'
2
+
3
+ module Scooter
4
+
5
+ describe Scooter::HttpDispatchers::Classifier do
6
+
7
+ let(:host) { double('host') }
8
+ let(:credentials) { double('credentials') }
9
+ let(:node_list) { [
10
+ {
11
+ "name" => "fbf2gpzzr4945ik.delivery.puppetlabs.net",
12
+ "check_ins" => [
13
+ {
14
+ "time" => "2016-06-06T18:28:27.686Z",
15
+ "explanation" => {
16
+ "00000000-0000-4000-8000-000000000000" => {
17
+ "value" => true,
18
+ "form" => [
19
+ "and",
20
+ {
21
+ "value" => true,
22
+ "form" => [
23
+ "~",
24
+ {
25
+ "path" => "name",
26
+ "value" => "fbf2gpzzr4945ik.delivery.puppetlabs.net"
27
+ },
28
+ ".*"
29
+ ]
30
+ }
31
+ ]
32
+ },
33
+ "a9649f0c-97bd-4394-964c-230a4b35f272" => {
34
+ "value" => true,
35
+ "form" => [
36
+ "and",
37
+ {
38
+ "value" => true,
39
+ "form" => [
40
+ "~",
41
+ {
42
+ "path" => "name",
43
+ "value" => "fbf2gpzzr4945ik.delivery.puppetlabs.net"
44
+ },
45
+ ".*"
46
+ ]
47
+ }
48
+ ]
49
+ },
50
+ "6c847b5c-51bc-49fa-ab1b-e20a9ef3474d" => {
51
+ "value" => true,
52
+ "form" => [
53
+ "or",
54
+ {
55
+ "value" => true,
56
+ "form" => [
57
+ "=",
58
+ {
59
+ "path" => "name",
60
+ "value" => "fbf2gpzzr4945ik.delivery.puppetlabs.net"
61
+ },
62
+ "fbf2gpzzr4945ik.delivery.puppetlabs.net"
63
+ ]
64
+ }
65
+ ]
66
+ },
67
+ "a07c4da1-9af7-4427-a99c-19efff80accb" => {
68
+ "value" => true,
69
+ "form" => [
70
+ "or",
71
+ {
72
+ "value" => true,
73
+ "form" => [
74
+ "=",
75
+ {
76
+ "path" => "name",
77
+ "value" => "fbf2gpzzr4945ik.delivery.puppetlabs.net"
78
+ },
79
+ "fbf2gpzzr4945ik.delivery.puppetlabs.net"
80
+ ]
81
+ }
82
+ ]
83
+ },
84
+ "6f1b8ba3-652c-40c6-a7c4-fe318352db93" => {
85
+ "value" => true,
86
+ "form" => [
87
+ "or",
88
+ {
89
+ "value" => true,
90
+ "form" => [
91
+ "=",
92
+ {
93
+ "path" => "name",
94
+ "value" => "fbf2gpzzr4945ik.delivery.puppetlabs.net"
95
+ },
96
+ "fbf2gpzzr4945ik.delivery.puppetlabs.net"
97
+ ]
98
+ }
99
+ ]
100
+ },
101
+ "b9e64b26-7b65-42f9-a9a1-bfbbfd4cc7a8" => {
102
+ "value" => true,
103
+ "form" => [
104
+ "and",
105
+ {
106
+ "value" => true,
107
+ "form" => [
108
+ "~",
109
+ {
110
+ "path" => [
111
+ "fact",
112
+ "aio_agent_version"
113
+ ],
114
+ "value" => "1.5.0.31"
115
+ },
116
+ ".+"
117
+ ]
118
+ }
119
+ ]
120
+ },
121
+ "06042e9b-45c9-4add-bce1-d9034d5de16b" => {
122
+ "value" => true,
123
+ "form" => [
124
+ "or",
125
+ {
126
+ "value" => true,
127
+ "form" => [
128
+ "=",
129
+ {
130
+ "path" => "name",
131
+ "value" => "fbf2gpzzr4945ik.delivery.puppetlabs.net"
132
+ },
133
+ "fbf2gpzzr4945ik.delivery.puppetlabs.net"
134
+ ]
135
+ }
136
+ ]
137
+ },
138
+ "773c9b5a-e8c7-49ea-8931-f2e020383f21" => {
139
+ "value" => true,
140
+ "form" => [
141
+ "or",
142
+ {
143
+ "value" => true,
144
+ "form" => [
145
+ "=",
146
+ {
147
+ "path" => "name",
148
+ "value" => "fbf2gpzzr4945ik.delivery.puppetlabs.net"
149
+ },
150
+ "fbf2gpzzr4945ik.delivery.puppetlabs.net"
151
+ ]
152
+ }
153
+ ]
154
+ },
155
+ "329210bb-de3a-43f3-a732-73905f4e57ac" => {
156
+ "value" => true,
157
+ "form" => [
158
+ "and",
159
+ {
160
+ "value" => true,
161
+ "form" => [
162
+ "~",
163
+ {
164
+ "path" => [
165
+ "fact",
166
+ "aio_agent_version"
167
+ ],
168
+ "value" => "1.5.0.31"
169
+ },
170
+ ".+"
171
+ ]
172
+ }
173
+ ]
174
+ },
175
+ "40b72723-f191-4153-b81c-1f6531c5a9cd" => {
176
+ "value" => true,
177
+ "form" => [
178
+ "or",
179
+ {
180
+ "value" => true,
181
+ "form" => [
182
+ "=",
183
+ {
184
+ "path" => "name",
185
+ "value" => "fbf2gpzzr4945ik.delivery.puppetlabs.net"
186
+ },
187
+ "fbf2gpzzr4945ik.delivery.puppetlabs.net"
188
+ ]
189
+ }
190
+ ]
191
+ }
192
+ },
193
+ "classification" => {
194
+ "classes" => {
195
+ "pe_repo" => {},
196
+ "pe_repo::platform::el_7_x86_64" => {},
197
+ "puppet_enterprise::profile::mcollective::agent" => {},
198
+ "pe_console_prune" => {
199
+ "prune_upto" => "30"
200
+ },
201
+ "puppet_enterprise::profile::puppetdb" => {},
202
+ "puppet_enterprise::profile::agent" => {},
203
+ "puppet_enterprise::license" => {},
204
+ "puppet_enterprise::profile::orchestrator" => {},
205
+ "puppet_enterprise::profile::master" => {},
206
+ "puppet_enterprise::profile::master::mcollective" => {},
207
+ "puppet_enterprise::profile::console" => {},
208
+ "puppet_enterprise::profile::mcollective::peadmin" => {},
209
+ "puppet_enterprise" => {
210
+ "mcollective_middleware_hosts" => [
211
+ "fbf2gpzzr4945ik.delivery.puppetlabs.net"
212
+ ],
213
+ "use_application_services" => true,
214
+ "database_host" => "fbf2gpzzr4945ik.delivery.puppetlabs.net",
215
+ "puppetdb_host" => "fbf2gpzzr4945ik.delivery.puppetlabs.net",
216
+ "database_port" => "5432",
217
+ "classifier_database_user" => "DFGhjlkj",
218
+ "orchestrator_database_user" => "Orc3Str8R",
219
+ "database_ssl" => true,
220
+ "activity_database_user" => "adsfglkj",
221
+ "puppet_master_host" => "fbf2gpzzr4945ik.delivery.puppetlabs.net",
222
+ "certificate_authority_host" => "fbf2gpzzr4945ik.delivery.puppetlabs.net",
223
+ "console_port" => "443",
224
+ "rbac_database_user" => "RbhNBklm",
225
+ "puppetdb_database_name" => "pe-puppetdb",
226
+ "puppetdb_database_user" => "mYpdBu3r",
227
+ "pcp_broker_host" => "fbf2gpzzr4945ik.delivery.puppetlabs.net",
228
+ "puppetdb_port" => "8081",
229
+ "database_cert_auth" => false,
230
+ "console_host" => "fbf2gpzzr4945ik.delivery.puppetlabs.net"
231
+ },
232
+ "puppet_enterprise::profile::amq::broker" => {},
233
+ "puppet_enterprise::profile::certificate_authority" => {}
234
+ },
235
+ "variables" => {},
236
+ "environment" => "production"
237
+ },
238
+ "transaction_uuid" => "a3efb727-10e9-4bc0-b5f0-69ed74f30c22"
239
+ }
240
+ ]
241
+ }
242
+ ] }
243
+
244
+ let(:group_list) { [
245
+ {
246
+ "parent" => "00000000-0000-4000-8000-000000000000",
247
+ "environment_trumps" => false,
248
+ "name" => "All Nodes",
249
+ "rule" => [
250
+ "and",
251
+ [
252
+ "~",
253
+ "name",
254
+ ".*"
255
+ ]
256
+ ],
257
+ "variables" => {},
258
+ "id" => "00000000-0000-4000-8000-000000000000",
259
+ "environment" => "production",
260
+ "classes" => {}
261
+ },
262
+ {
263
+ "parent" => "aabb8071-df67-4340-aded-e4f598a3ca0b",
264
+ "environment_trumps" => false,
265
+ "name" => "PE Certificate Authority",
266
+ "rule" => [
267
+ "or",
268
+ [
269
+ "=",
270
+ "name",
271
+ "fbf2gpzzr4945ik.delivery.puppetlabs.net"
272
+ ]
273
+ ],
274
+ "variables" => {},
275
+ "id" => "06042e9b-45c9-4add-bce1-d9034d5de16b",
276
+ "environment" => "production",
277
+ "classes" => {
278
+ "puppet_enterprise::profile::certificate_authority" => {}
279
+ }
280
+ }] }
281
+ let(:environment_list) { [
282
+ {
283
+ "name" => "agent-specified",
284
+ "sync_succeeded" => true
285
+ },
286
+ {
287
+ "name" => "production",
288
+ "sync_succeeded" => true
289
+ }
290
+ ] }
291
+ let(:class_list) { [
292
+ {
293
+ "name" => "pe_accounts",
294
+ "environment" => "production",
295
+ "parameters" => {
296
+ "manage_groups" => "true",
297
+ "manage_users" => "true",
298
+ "manage_sudoers" => "false",
299
+ "data_store" => "'namespace'",
300
+ "data_namespace" => "'pe_accounts::data'",
301
+ "sudoers_path" => "'/etc/sudoers'"
302
+ }
303
+ },
304
+ {
305
+ "name" => "pe_accounts::data",
306
+ "environment" => "production",
307
+ "parameters" => {}
308
+ },
309
+ {
310
+ "name" => "pe_accounts::groups",
311
+ "environment" => "production",
312
+ "parameters" => {
313
+ "groups_hash" => nil
314
+ }
315
+ },
316
+ {
317
+ "name" => "pe_concat::setup",
318
+ "environment" => "production",
319
+ "parameters" => {}
320
+ }] }
321
+
322
+ subject { HttpDispatchers::ConsoleDispatcher.new(host, credentials) }
323
+
324
+ context 'with a beaker host passed in' do
325
+
326
+ unixhost = { roles: ['test_role'],
327
+ 'platform' => 'debian-7-x86_64' }
328
+ let(:host) { Beaker::Host.create('test.com', unixhost, {}) }
329
+ let(:credentials) { { login: 'Ziggy', password: 'Stardust' } }
330
+
331
+ before do
332
+ expect(Scooter::Utilities::BeakerUtilities).to receive(:pe_ca_cert_file).and_return('cert file')
333
+ expect(Scooter::Utilities::BeakerUtilities).to receive(:get_public_ip).and_return('public_ip')
334
+ expect(subject).not_to be_nil
335
+ end
336
+
337
+ describe '.update_classes' do
338
+ before do
339
+ # find the index of the default Faraday::Adapter::NetHttp handler
340
+ # and replace it with the Test adapter
341
+ index = subject.connection.builder.handlers.index(Faraday::Adapter::NetHttp)
342
+ subject.connection.builder.swap(index, Faraday::Adapter::Test) do |stub|
343
+ stub.post('/classifier-api/v1/update-classes') { [201, {}] }
344
+ end
345
+ end
346
+ it 'updates the classes for all environments' do
347
+ expect { subject.update_classes }.not_to raise_error
348
+ expect(subject.update_classes.status).to eq(201)
349
+ end
350
+ it 'updates the classes for a single environment if specified' do
351
+ expect { subject.update_classes('test_environment') }.not_to raise_error
352
+ response = subject.update_classes('test_environment')
353
+ expect(response.status).to eq(201)
354
+ hashed_query = CGI.parse(response.env.url.query)
355
+ expect(hashed_query).to eq('environment' => ['test_environment'])
356
+ end
357
+ end
358
+
359
+ describe '.pin_nodes' do
360
+ it 'works when passed a set of nodes' do
361
+ expect(subject.connection).to receive(:post).with('v1/groups/group_id/pin')
362
+ expect { subject.pin_nodes("group_id", ["node1", "node2"]) }.not_to raise_error
363
+ end
364
+ end
365
+
366
+ describe '.unpin_nodes' do
367
+ it 'works when passed a set of nodes' do
368
+ expect(subject.connection).to receive(:post).with('v1/groups/group_id/unpin')
369
+ expect { subject.unpin_nodes("group_id", ["node1", "node2"]) }.not_to raise_error
370
+ end
371
+ end
372
+
373
+ describe '.get_list_of_node_groups' do
374
+ before do
375
+ # find the index of the default Faraday::Adapter::NetHttp handler
376
+ # and replace it with the Test adapter
377
+ index = subject.connection.builder.handlers.index(Faraday::Adapter::NetHttp)
378
+ subject.connection.builder.swap(index, Faraday::Adapter::Test) do |stub|
379
+ stub.get('classifier-api/v1/groups') { |env| [200, {}, group_list] }
380
+ end
381
+ end
382
+ it 'returns list of groups' do
383
+ expect { subject.get_list_of_node_groups }.not_to raise_error
384
+ list = subject.get_list_of_node_groups
385
+ expect(list.is_a?(Array)).to be true
386
+ end
387
+ end
388
+
389
+ describe '.get_list_of_nodes' do
390
+ before do
391
+ # find the index of the default Faraday::Adapter::NetHttp handler
392
+ # and replace it with the Test adapter
393
+ index = subject.connection.builder.handlers.index(Faraday::Adapter::NetHttp)
394
+ subject.connection.builder.swap(index, Faraday::Adapter::Test) do |stub|
395
+ stub.get('classifier-api/v1/nodes') { |env| [200, {}, node_list] }
396
+ end
397
+ end
398
+ it 'returns list of nodes' do
399
+ expect { subject.get_list_of_nodes }.not_to raise_error
400
+ list = subject.get_list_of_nodes
401
+ expect(list.is_a?(Array)).to be true
402
+ end
403
+ end
404
+
405
+ describe '.get_list_of_environments' do
406
+ before do
407
+ # find the index of the default Faraday::Adapter::NetHttp handler
408
+ # and replace it with the Test adapter
409
+ index = subject.connection.builder.handlers.index(Faraday::Adapter::NetHttp)
410
+ subject.connection.builder.swap(index, Faraday::Adapter::Test) do |stub|
411
+ stub.get('classifier-api/v1/environments') { |env| [200, {}, environment_list] }
412
+ end
413
+ end
414
+ it 'returns list of environments' do
415
+ expect { subject.get_list_of_environments }.not_to raise_error
416
+ list = subject.get_list_of_environments
417
+ expect(list.is_a?(Array)).to be true
418
+ end
419
+ end
420
+
421
+ describe '.get_list_of_classes' do
422
+ before do
423
+ # find the index of the default Faraday::Adapter::NetHttp handler
424
+ # and replace it with the Test adapter
425
+ index = subject.connection.builder.handlers.index(Faraday::Adapter::NetHttp)
426
+ subject.connection.builder.swap(index, Faraday::Adapter::Test) do |stub|
427
+ stub.get('classifier-api/v1/classes') { |env| [200, {}, class_list] }
428
+ end
429
+ end
430
+ it 'returns list of classes' do
431
+ expect { subject.get_list_of_classes }.not_to raise_error
432
+ list = subject.get_list_of_classes
433
+ expect(list.is_a?(Array)).to be true
434
+ end
435
+ end
436
+
437
+ describe '.nodes_match?' do
438
+ before do
439
+ # find the index of the default Faraday::Adapter::NetHttp handler
440
+ # and replace it with the Test adapter
441
+ index = subject.connection.builder.handlers.index(Faraday::Adapter::NetHttp)
442
+ subject.connection.builder.swap(index, Faraday::Adapter::Test) do |stub|
443
+ stub.get('classifier-api/v1/nodes') { |env| [200, {}, node_list] }
444
+ end
445
+ end
446
+ it 'nodes do not match' do
447
+ expect(subject.nodes_match?(node_list.dup.push('another_array_item'))).to be false
448
+ end
449
+ it 'nodes match' do
450
+ expect(subject.nodes_match?(node_list)).to be true
451
+ end
452
+
453
+ end
454
+
455
+ describe '.groups_match?' do
456
+ before do
457
+ # find the index of the default Faraday::Adapter::NetHttp handler
458
+ # and replace it with the Test adapter
459
+ index = subject.connection.builder.handlers.index(Faraday::Adapter::NetHttp)
460
+ subject.connection.builder.swap(index, Faraday::Adapter::Test) do |stub|
461
+ stub.get('classifier-api/v1/groups') { |env| [200, {}, group_list] }
462
+ end
463
+ end
464
+ it 'groups do not match' do
465
+ expect(subject.groups_match?(group_list.dup.push('another_array_item'))).to be false
466
+ end
467
+ it 'groups match' do
468
+ expect(subject.groups_match?(group_list)).to be true
469
+ end
470
+
471
+ end
472
+
473
+ describe '.classes_match?' do
474
+ before do
475
+ # find the index of the default Faraday::Adapter::NetHttp handler
476
+ # and replace it with the Test adapter
477
+ index = subject.connection.builder.handlers.index(Faraday::Adapter::NetHttp)
478
+ subject.connection.builder.swap(index, Faraday::Adapter::Test) do |stub|
479
+ stub.get('classifier-api/v1/classes') { |env| [200, {}, class_list] }
480
+ end
481
+ end
482
+ it 'classes do not match' do
483
+ expect(subject.classes_match?(class_list.dup.push('another_array_item'))).to be false
484
+ end
485
+ it 'classes match' do
486
+ expect(subject.classes_match?(class_list)).to be true
487
+ end
488
+
489
+ end
490
+
491
+ describe '.environments_match?' do
492
+ before do
493
+ # find the index of the default Faraday::Adapter::NetHttp handler
494
+ # and replace it with the Test adapter
495
+ index = subject.connection.builder.handlers.index(Faraday::Adapter::NetHttp)
496
+ subject.connection.builder.swap(index, Faraday::Adapter::Test) do |stub|
497
+ stub.get('classifier-api/v1/environments') { |env| [200, {}, environment_list] }
498
+ end
499
+ end
500
+ it 'environments do not match' do
501
+ expect(subject.environments_match?(environment_list.dup.push('another_array_item'))).to be false
502
+ end
503
+ it 'environments match' do
504
+ expect(subject.environments_match?(environment_list)).to be true
505
+ end
506
+
507
+ end
508
+
509
+ describe '.classifier_database_matches_self?' do
510
+ before do
511
+ # find the index of the default Faraday::Adapter::NetHttp handler
512
+ # and replace it with the Test adapter
513
+ index = subject.connection.builder.handlers.index(Faraday::Adapter::NetHttp)
514
+ subject.connection.builder.swap(index, Faraday::Adapter::Test) do |stub|
515
+ stub.get('classifier-api/v1/nodes') { |env| env[:url].to_s == "https://test.com:4433/classifier-api/v1/nodes" ?
516
+ [200, [], node_list] :
517
+ [200, [], node_list.dup.push('another_array_item')] }
518
+ stub.get('classifier-api/v1/environments') { |env| env[:url].to_s == "https://test.com:4433/classifier-api/v1/environments" ?
519
+ [200, [], environment_list] :
520
+ [200, [], environment_list.dup.push('another_array_item')] }
521
+ stub.get('classifier-api/v1/groups') { |env| env[:url].to_s == "https://test.com:4433/classifier-api/v1/groups" ?
522
+ [200, [], group_list] :
523
+ [200, [], group_list.dup.push('another_array_item')] }
524
+ stub.get('classifier-api/v1/classes') { |env| env[:url].to_s == "https://test.com:4433/classifier-api/v1/classes" ?
525
+ [200, [], class_list] :
526
+ [200, [], class_list.dup.push('another_array_item')] }
527
+ end
528
+ expect(subject).to receive(:create_default_connection).with(any_args).twice.and_return(subject.connection)
529
+ expect(Scooter::Utilities::BeakerUtilities).to receive(:get_public_ip).and_return('public_ip')
530
+ end
531
+ it 'compare with self' do
532
+ expect(subject.classifier_database_matches_self?('test.com')).to be_truthy
533
+ end
534
+
535
+ it 'compare with different' do
536
+ expect(subject.faraday_logger).to receive(:warn).with /Nodes do not match/
537
+ expect(subject.classifier_database_matches_self?('test2.com')).to be_falsey
538
+ end
539
+ end
540
+ end
541
+ end
542
+ end