pritunl_api_client 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 57de66a4a4b74e8312eeacb682b1ce8060736965
4
+ data.tar.gz: 10234f4f8f1bb0ba189516c3c0dec406d9ec5df5
5
+ SHA512:
6
+ metadata.gz: 5cf7ad74463442d38984f0c1bd1a4a3bf43f06edaa57a4b0631539a843cf44b40171206ef162f1cced53a9cd9a1fcec52a3095d1c427272e23ba02d21cc04525
7
+ data.tar.gz: 37b243f542fc76c9da1f5ed4e227ea5c78ef6091eb0220cbb47ea091493286c3492fcc42da6aab76ce6d4986b8992ce137860ca26d104eb618244e5542cd68f3
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pritunl_api_client.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Eric Terry
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,518 @@
1
+ # Pritunl API Client
2
+
3
+ API client for Pritunl written in Ruby.
4
+
5
+ [Pritunl](https://github.com/pritunl/pritunl) is a distributed enterprise
6
+ vpn server built using the OpenVPN protocol. See the official Pritunl API
7
+ documentation here: https://pritunl.com/api.html. I am not affiliated with
8
+ Pritunl at all, but couldn't find a Ruby client for their API. So I scratched
9
+ my own itch and created it myself.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ gem install pritunl_api_client
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```ruby
20
+ require 'pritunl_api_client'
21
+
22
+ @pritunl = PritunlApiClient::Client.new(
23
+ base_url: 'https://localhost:9700',
24
+ api_token: 'p7g444S3IZ5wmFvmzWmx14qACXdzQ25b',
25
+ api_secret: 'OpS9fjxkPI3DclkdKDDr6mqYVd0DJh4i',
26
+ verify_ssl: false
27
+ )
28
+ ```
29
+
30
+ ## Ping
31
+
32
+ ### Server healthcheck.
33
+
34
+ ```ruby
35
+ @pritunl.ping
36
+ ```
37
+
38
+ ## Status
39
+
40
+ ### Returns general information about the pritunl server.
41
+
42
+ ```ruby
43
+ @pritunl.status
44
+
45
+ {
46
+ "host_count" => 1,
47
+ "servers_online" => 1,
48
+ "hosts_online" => 1,
49
+ "server_count" => 2,
50
+ "server_version" => "1.11.813.26",
51
+ "public_ip" => "10.55.87.4",
52
+ "user_count" => 1,
53
+ "notification" => "",
54
+ "users_online" => 1,
55
+ "local_networks" => ["10.55.87.3/31", "10.2.214.0/31"],
56
+ "current_host" => "0f273a6c32ed45259c1ecb1ec3ac05ce",
57
+ "org_count" => 2
58
+ }
59
+ ```
60
+
61
+ ## Log
62
+
63
+ ### Returns a list of server log entries sorted by time.
64
+
65
+ ```ruby
66
+ @pritunl.log
67
+
68
+ [
69
+ {
70
+ "timestamp" => 1450429682,
71
+ "message" => "Deleted organization 'org1'.",
72
+ "id" => "567386a32221390ea53d8047"
73
+ },
74
+ {
75
+ "timestamp" => 1450429682,
76
+ "message" => "Deleted user 'user1'.",
77
+ "id" => "567386a32221390ea53d8045"
78
+ },
79
+ {
80
+ "timestamp" => 1450429681,
81
+ "message" => "Enabled user 'user2'.",
82
+ "id" => "567386a22221390ea53d8042"
83
+ }
84
+ ]
85
+ ```
86
+
87
+ ## Events
88
+
89
+ ### Get a list of events (will poll up to 30 seconds)
90
+
91
+ ```ruby
92
+ @pritunl.event( cursor: '55e9f1f1b0e730245677dc31' )
93
+
94
+ [
95
+ {
96
+ "id" => "55e9f1f1b0e730245677dc31",
97
+ "type" => "users_updated",
98
+ "timestamp" => 1388495793,
99
+ "resource_id" => "55e9f1f8b0e730245677dc34"
100
+ },
101
+ {
102
+ "id" => "55e9f1f2b0e730245677dc32",
103
+ "type" => "server_organizations_updated",
104
+ "timestamp" => 1388495805,
105
+ "resource_id" => "55e9f1f8b0e730245677dc33"
106
+ }
107
+ ]
108
+ ```
109
+
110
+ ## Settings
111
+
112
+ ### Get system settings.
113
+
114
+ ```ruby
115
+ @pritunl.settings.all
116
+
117
+ {
118
+ "username" => "user6",
119
+ "sso_admin" => nil,
120
+ "theme" => "dark",
121
+ "sso" => nil,
122
+ "sso_match" => nil,
123
+ "server_cert" => "-----BEGIN CERTIFICATE----------END CERTIFICATE-----",
124
+ "public_address" => "10.5.8.46",
125
+ "routed_subnet6" => nil,
126
+ "email_username" => "user1",
127
+ "sso_saml_issuer_url" => nil,
128
+ "sso_saml_cert" => nil,
129
+ "sso_token" => nil,
130
+ "email_password" => true,
131
+ "sso_onelogin_key" => nil,
132
+ "email_server" => "smtp.example.com",
133
+ "auditing" => nil,
134
+ "sso_secret" => nil,
135
+ "server_key" => "-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----",
136
+ "default" => nil,
137
+ "sso_host" => nil,
138
+ "public_address6" => "2605:1480:2:a210::1",
139
+ "secret" => "9D1ZJTscrr2mK4Xnxw76ltmpwnH7udeO",
140
+ "sso_okta_token" => nil,
141
+ "sso_saml_url" => nil,
142
+ "token" => "UQRM0R3bsXDpy3p6nqtjfrbjujSadaAx",
143
+ "sso_org" => nil,
144
+ "email_from" => "first.last@example.com"
145
+ }
146
+ ```
147
+
148
+ ### Change the system settings.
149
+
150
+ ```ruby
151
+ @pritunl.settings.update( theme: 'dark' )
152
+
153
+ @pritunl.settings.update(
154
+ email_username: 'user1',
155
+ email_password: '12345',
156
+ email_server: 'smtp.example.com',
157
+ email_from: 'first.last@example.com'
158
+ )
159
+ ```
160
+
161
+ ## Users
162
+
163
+ ### Returns a list of users in an organization sorted by name.
164
+
165
+ ```ruby
166
+ @pritunl.user.all( organization_id: org['id'] )
167
+
168
+ [
169
+ {
170
+ "auth_type" => "local",
171
+ "status" => false,
172
+ "dns_servers" => nil,
173
+ "otp_secret" => "OPT4HTURJTW6JLQN",
174
+ "dns_mapping" => nil,
175
+ "dns_suffix" => nil,
176
+ "servers" => [
177
+ {
178
+ "status" => false,
179
+ "platform" => nil,
180
+ "server_id" => "567369be2231390ea53d76d4",
181
+ "local_address" => "10.139.82.6",
182
+ "remote_address" => "10.139.82.7",
183
+ "virt_address6" => "fd00:c0a8:e800:0:10.139.82.6",
184
+ "virt_address" => "10.139.82.6",
185
+ "name" => "server1",
186
+ "real_address" => "8.8.8.8:41536",
187
+ "connected_since" => 1388498640,
188
+ "id" => "55e9f995b0e73033d45b44da",
189
+ "device_name" => nil
190
+ }
191
+ ],
192
+ "disabled" => false,
193
+ "network_links" => [],
194
+ "sso" => nil,
195
+ "bypass_secondary" => false,
196
+ "id" => "55e9f98cb0e73033d45b44d7",
197
+ "audit" => false,
198
+ "name" => "user0",
199
+ "organization_name" => "org1",
200
+ "gravatar" => true,
201
+ "otp_auth" => false,
202
+ "organization" => "55e9f7c7b0e73033d45b44d4",
203
+ "type" => "client",
204
+ "email" => "user0@example.com"
205
+ }
206
+ ]
207
+ ```
208
+
209
+ ### Returns a user from an organization.
210
+
211
+ ```ruby
212
+ @pritunl.user.find( user['id'], organization_id: org['id'] )
213
+
214
+ {
215
+ "auth_type" => "local",
216
+ "dns_servers" => nil,
217
+ "otp_secret" => "OPT4HTURJTW6JLQN",
218
+ "dns_suffix" => nil,
219
+ "disabled" => true,
220
+ "bypass_secondary" => false,
221
+ "id" => "55e9f98cb0e73033d45b44d7",
222
+ "name" => "user0",
223
+ "organization_name" => "org1",
224
+ "organization" => "55e9f7c7b0e73033d45b44d4",
225
+ "type" => "client",
226
+ "email" => "user0@example.com"
227
+ }
228
+ ```
229
+
230
+ ### Create a new user in an organization. An array of users can be sent for bulk adding users.
231
+
232
+ ```ruby
233
+ @pritunl.user.create(
234
+ organization_id: org['id'],
235
+ name: 'new_user',
236
+ email: 'new_user@example.com',
237
+ disabled: true
238
+ )
239
+ ```
240
+
241
+ ### Rename or disabled an existing user in an organization. Disabling will also disconnect the user.
242
+
243
+ ```ruby
244
+ @pritunl.user.update( user['id'],
245
+ organization_id: org['id'],
246
+ name: 'new_name',
247
+ email: 'new_email@example.com',
248
+ disabled: false
249
+ )
250
+ ```
251
+
252
+ ### Delete an existing user in an organization, this will disconnect the user.
253
+
254
+ ```ruby
255
+ @pritunl.user.delete( user['id'], organization_id: org['id'] )
256
+ ```
257
+
258
+ ### Generate a new two-step authentication secret for an existing user.
259
+
260
+ ```ruby
261
+ @pritunl.user.otp_secret( user['id'], organization_id: org['id'] )
262
+ ```
263
+
264
+ ## Organizations
265
+
266
+ ### Returns a list of organizations on the server sorted by name.
267
+
268
+ ```ruby
269
+ @pritunl.organization.all
270
+
271
+ [
272
+ {
273
+ "user_count" => 512,
274
+ "id" => "55e99499b0e7300fef77e2b1",
275
+ "name" => "org1"
276
+ },
277
+ {
278
+ "user_count" => 1024,
279
+ "id" => "55e9f1d4b0e730245677dc2d",
280
+ "name" => "org2"
281
+ }
282
+ ]
283
+ ```
284
+
285
+ ### Returns an organization.
286
+
287
+ ```ruby
288
+ @pritunl.organization.find( org['id'] )
289
+
290
+ {
291
+ "user_count" => 512,
292
+ "id" => "55e99499b0e7300fef77e2b1",
293
+ "name" => "org1"
294
+ }
295
+ ```
296
+
297
+ ### Create a new organization.
298
+
299
+ ```ruby
300
+ @pritunl.organization.create( name: 'new_org' )
301
+ ```
302
+
303
+ ### Rename an existing organization.
304
+
305
+ ```ruby
306
+ @pritunl.organization.update( org['id'], name: 'new_name' )
307
+ ```
308
+
309
+ ### Delete an existing organization.
310
+
311
+ ```ruby
312
+ @pritunl.organization.delete( org['id'] )
313
+ ```
314
+
315
+ ## Keys
316
+
317
+ ### Download a users key tar archive.
318
+
319
+ ```ruby
320
+ @pritunl.key.download_tar( organization_id: org['id'], user_id: user['id'], path: 'output.tar' )
321
+ ```
322
+
323
+ ### Download a users onc key zip archive.
324
+
325
+ ```ruby
326
+ @pritunl.key.download_zip( organization_id: org['id'], user_id: user['id'], path: 'output.zip' )
327
+ ```
328
+
329
+ ### Generate a temporary url to download a users key archive.
330
+
331
+ ```ruby
332
+ @pritunl.key.temporary_url( organization_id: org['id'], user_id: user['id'] )
333
+
334
+ {
335
+ "view_url" => "/k/MjyaVvGk",
336
+ "key_url" => "/key/4f5bd04d85414e20b0a451d642dab06d.tar",
337
+ "uri_url" => "/ku/MjyaVvGk",
338
+ "key_zip_url" => "/key/4f5bd04d85414e20b0a451d642dab06d.zip",
339
+ "key_onc_url" => "/key_onc/4f5bd04d85414e20b0a451d642dab06d.zip",
340
+ "id" => "4f5bd04d85414e20b0a451d642dab06d"
341
+ }
342
+ ```
343
+
344
+ ## Servers
345
+
346
+ ### Returns a list of servers.
347
+
348
+ ```ruby
349
+ @pritunl.server.all
350
+ ```
351
+
352
+ ### Returns a server.
353
+
354
+ ```ruby
355
+ @pritunl.server.find( server['id'] )
356
+
357
+ {
358
+ "status" => "pending",
359
+ "lzo_compression" => false,
360
+ "dns_servers" => ["8.8.4.4"],
361
+ "protocol" => "udp",
362
+ "ping_interval" => 10,
363
+ "dns_mapping" => false,
364
+ "network_mode" => "tunnel",
365
+ "debug" => false,
366
+ "network_end" => nil,
367
+ "bind_address" => nil,
368
+ "link_ping_interval" => 1,
369
+ "hash" => "sha1",
370
+ "ipv6_firewall" => true,
371
+ "inter_client" => true,
372
+ "id" => "5678d5286231390ea53eda96",
373
+ "network_start" => nil,
374
+ "network" => "10.11.6.0/24",
375
+ "local_networks" => [],
376
+ "uptime" => nil,
377
+ "user_count" => 0,
378
+ "name" => "server1",
379
+ "dh_param_bits" => 2048,
380
+ "max_clients" => 2048,
381
+ "users_online" => 0,
382
+ "replica_count" => 1,
383
+ "link_ping_timeout" => 5,
384
+ "port" => 12533,
385
+ "devices_online" => 0,
386
+ "ping_timeout" => 60,
387
+ "mode" => "all_traffic",
388
+ "ipv6" => false,
389
+ "otp_auth" => false,
390
+ "jumbo_frames" => false,
391
+ "multi_device" => false,
392
+ "search_domain" => "example.com",
393
+ "cipher" => "aes256"
394
+ }
395
+ ```
396
+
397
+ ### Create a new server.
398
+
399
+ ```ruby
400
+ @pritunl.server.create(
401
+ name: 'server1',
402
+ network: '10.11.6.0/24',
403
+ bind_address: nil,
404
+ port: 12533,
405
+ protocol: 'udp',
406
+ dh_param_bits: 2048,
407
+ mode: 'all_traffic',
408
+ network_mode: 'tunnel',
409
+ network_start: nil,
410
+ network_end: nil,
411
+ multi_device: false,
412
+ local_networks: [],
413
+ dns_servers: ['8.8.4.4'],
414
+ search_domain: 'pritunl.com',
415
+ otp_auth: false,
416
+ cipher: 'aes256',
417
+ jumbo_frames: false,
418
+ lzo_compression: false,
419
+ inter_client: true,
420
+ ping_interval: 10,
421
+ ping_timeout: 60,
422
+ max_clients: 2048,
423
+ replica_count: 1,
424
+ debug: false
425
+ )
426
+ ```
427
+
428
+ ### Update an existing server.
429
+
430
+ ```ruby
431
+ @pritunl.server.update( server['id'], name: 'server1-rename', dns_servers: ['8.8.8.8', '8.8.4.4'] )
432
+ ```
433
+
434
+ ### Delete an existing server.
435
+
436
+ ```ruby
437
+ @pritunl.server.delete( server['id'] )
438
+ ```
439
+
440
+ ### Start, stop or restart an existing server.
441
+
442
+ ```ruby
443
+ @pritunl.server.start( server['id'] )
444
+ @pritunl.server.stop( server['id'] )
445
+ @pritunl.server.restart( server['id'] )
446
+ ```
447
+
448
+ ### Returns a list of organizations attached to a server.
449
+
450
+ ```ruby
451
+ @pritunl.server.organizations( server['id'] )
452
+
453
+ [
454
+ {
455
+ "id" => "5678d0f48831390da53ef8ae",
456
+ "name" => "org1",
457
+ "server" => "5678d5286231390ea53eda96"
458
+ },
459
+ {
460
+ "id" => "5678d0f48831392ba71ad3cb",
461
+ "name" => "org2",
462
+ "server" => "5678d5286231390ea53eda96"
463
+ }
464
+ ]
465
+ ```
466
+
467
+ ### Attach an organization to an existing server.
468
+
469
+ ```ruby
470
+ @pritunl.server.attach_organization( server['id'], organization_id: org['id'] )
471
+
472
+ {
473
+ "id" => "5678d0f48831390da53ef8ae",
474
+ "name" => "org1",
475
+ "server" => "5678d5286231390ea53eda96"
476
+ }
477
+ ```
478
+
479
+ ### Remove an organization from an existing server.
480
+
481
+ ```ruby
482
+ @pritunl.server.remove_organization( server['id'], organization_id: org['id'] )
483
+ ```
484
+
485
+ ### Get the output of a server.
486
+
487
+ ```ruby
488
+ @pritunl.server.output( server['id'] )
489
+
490
+ {
491
+ "id" => "5678d5286231390ea53eda96",
492
+ "output" => [
493
+ "[patient-forest-4024] Mon Dec 21 23:45:15 2015 OpenVPN 2.3.2 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [eurephia] [MH] [IPv6] built on Dec 1 2014",
494
+ "[patient-forest-4024] Mon Dec 21 23:45:15 2015 Control Channel Authentication: tls-auth using INLINE static key file",
495
+ "[patient-forest-4024] Mon Dec 21 23:45:15 2015 TUN/TAP device tun11 opened",
496
+ "[patient-forest-4024] Mon Dec 21 23:45:15 2015 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0",
497
+ "[patient-forest-4024] Mon Dec 21 23:45:15 2015 /sbin/ip link set dev tun11 up mtu 1500",
498
+ "[patient-forest-4024] Mon Dec 21 23:45:15 2015 /sbin/ip addr add dev tun11 10.11.6.1/24 broadcast 10.11.6.255",
499
+ "[patient-forest-4024] Mon Dec 21 23:45:15 2015 UDPv4 link local (bound): [undef]",
500
+ "[patient-forest-4024] Mon Dec 21 23:45:15 2015 UDPv4 link remote: [undef]",
501
+ "[patient-forest-4024] Mon Dec 21 23:45:15 2015 Initialization Sequence Completed"
502
+ ]
503
+ }
504
+ ```
505
+
506
+ ### Clear the output of a server.
507
+
508
+ ```ruby
509
+ @pritunl.server.clear_output( server['id'] )
510
+ ```
511
+
512
+ ## Contributing
513
+
514
+ Bug reports and pull requests are welcome on GitHub at https://github.com/eterry1388/pritunl_api_client.
515
+
516
+ ## License
517
+
518
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new( :spec )
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'pritunl_api_client'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require 'pry'
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,103 @@
1
+ require_relative 'pritunl_api_client/api'
2
+ require_relative 'pritunl_api_client/settings'
3
+ require_relative 'pritunl_api_client/organization'
4
+ require_relative 'pritunl_api_client/user'
5
+ require_relative 'pritunl_api_client/key'
6
+ require_relative 'pritunl_api_client/server'
7
+
8
+ # API client for Pritunl. Pritunl is a distributed enterprise vpn server built
9
+ # using the OpenVPN protocol. See the official Pritunl API documentation here:
10
+ # https://pritunl.com/api.html. I am not affiliated with Pritunl at all, but
11
+ # couldn't find a Ruby client for their API. So I scratched my own itch and
12
+ # created it myself.
13
+ #
14
+ # @author {mailto:eterry1388@aol.com Eric Terry}
15
+ # @see https://github.com/eterry1388/pritunl_api_client
16
+ module PritunlApiClient
17
+
18
+ # Main interface to the Pritunl api
19
+ class Client
20
+
21
+ # @param base_url [String] Full URL to a running Pritunl server (include the "https://")
22
+ # @param api_token [String
23
+ # @param api_secret [String]
24
+ # @param verify_ssl [Boolean] Whether or not to verify SSL certificate
25
+ def initialize( base_url:, api_token:, api_secret:, verify_ssl: true )
26
+ @base_url = base_url
27
+ @api_token = api_token
28
+ @api_secret = api_secret
29
+ @verify_ssl = verify_ssl
30
+ @api = Api.new( base_url: base_url, api_token: api_token, api_secret: api_secret, verify_ssl: verify_ssl )
31
+ end
32
+
33
+ # Get a list of events (will poll up to 30 seconds)
34
+ #
35
+ # @param cursor [String, NilClass] Optional id of last event. If left out, only events
36
+ # that occurred after request is sent will be returned.
37
+ # @return [Array]
38
+ def event( cursor: nil )
39
+ @api.get( "/event/#{cursor}" )
40
+ end
41
+
42
+ # Server healthcheck
43
+ #
44
+ # @return [Boolean]
45
+ def ping
46
+ begin
47
+ @api.get( '/ping' ) == ''
48
+ rescue
49
+ false
50
+ end
51
+ end
52
+
53
+ # Returns general information about the pritunl server
54
+ #
55
+ # @return [Hash]
56
+ def status
57
+ @api.get( '/status' )
58
+ end
59
+
60
+ # Returns a list of server log entries
61
+ #
62
+ # @return [Array]
63
+ def log
64
+ @api.get( '/log' )
65
+ end
66
+
67
+ # Setting apis
68
+ #
69
+ # @return [PritunlApiClient::Settings]
70
+ def settings
71
+ @settings ||= Settings.new( @api )
72
+ end
73
+
74
+ # Organization apis
75
+ #
76
+ # @return [PritunlApiClient::Organization]
77
+ def organization
78
+ @organization ||= Organization.new( @api )
79
+ end
80
+
81
+ # User apis
82
+ #
83
+ # @return [PritunlApiClient::User]
84
+ def user
85
+ @user ||= User.new( @api )
86
+ end
87
+
88
+ # Key apis
89
+ #
90
+ # @return [PritunlApiClient::Key]
91
+ def key
92
+ @key ||= Key.new( @api )
93
+ end
94
+
95
+ # Server apis
96
+ #
97
+ # @return [PritunlApiClient::Server]
98
+ def server
99
+ @server ||= Server.new( @api )
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,121 @@
1
+ require 'rest-client'
2
+ require 'securerandom'
3
+ require 'base64'
4
+ require 'json'
5
+
6
+ module PritunlApiClient
7
+
8
+ # Low-level communication to api server
9
+ class Api
10
+
11
+ # @param base_url [String] Full URL to a running Pritunl server (include the "https://")
12
+ # @param api_token [String
13
+ # @param api_secret [String]
14
+ # @param verify_ssl [Boolean] Whether or not to verify SSL certificate]
15
+ def initialize( base_url:, api_token:, api_secret:, verify_ssl: true )
16
+ @api_token = api_token
17
+ @api_secret = api_secret
18
+ @client = RestClient::Resource.new( base_url, verify_ssl: verify_ssl )
19
+ end
20
+
21
+ # Send post request to api server
22
+ #
23
+ # @param path [String] URL path of api
24
+ # @param params [Hash, NilClass] Api parameters
25
+ # @return [Hash, Array, String] Response from api server
26
+ def post( path, params = nil )
27
+ headers = common_headers.merge( generate_auth_headers( path: path, params: params, method: 'POST' ) )
28
+ params = JSON.generate( params, space: ' ' ) if params
29
+ parse_data @client[path].post( params, headers )
30
+ end
31
+
32
+ # Send get request to api server
33
+ #
34
+ # @param path [String] URL path of api
35
+ # @param params [Hash, NilClass] Api parameters
36
+ # @return [Hash, Array, String] Response from api server
37
+ def get( path, params = nil )
38
+ parameters = { params: params }
39
+ parameters.merge!( common_headers )
40
+ parameters.merge!( generate_auth_headers( path: path, params: params, method: 'GET' ) )
41
+ parse_data @client[path].get( parameters )
42
+ end
43
+
44
+ # Send put request to api server
45
+ #
46
+ # @param path [String] URL path of api
47
+ # @param params [Hash, NilClass] Api parameters
48
+ # @return [Hash, Array, String] Response from api server
49
+ def put( path, params = nil )
50
+ headers = common_headers.merge( generate_auth_headers( path: path, params: params, method: 'PUT' ) )
51
+ params = JSON.generate( params, space: ' ' ) if params
52
+ parse_data @client[path].put( params, headers )
53
+ end
54
+
55
+ # Send delete request to api server
56
+ #
57
+ # @param path [String] URL path of api
58
+ # @param params [Hash, NilClass] Api parameters
59
+ # @return [Hash, Array, String] Response from api server
60
+ def delete( path, params = nil )
61
+ parameters = { params: params }
62
+ parameters.merge!( common_headers )
63
+ parameters.merge!( generate_auth_headers( path: path, params: params, method: 'DELETE' ) )
64
+ parse_data @client[path].delete( parameters )
65
+ end
66
+
67
+ # Send head request to api server
68
+ #
69
+ # @param path [String] URL path of api
70
+ # @param params [Hash, NilClass] Api parameters
71
+ # @return [Hash, Array, String] Response from api server
72
+ def head( path, params = nil )
73
+ headers = common_headers.merge( generate_auth_headers( path: path, params: params, method: 'HEAD' ) )
74
+ params = JSON.generate( params, space: ' ' ) if params
75
+ parse_data @client[path].head( params, headers )
76
+ end
77
+
78
+ private
79
+
80
+ # Common headers to add to every request
81
+ #
82
+ # @return [Hash]
83
+ def common_headers
84
+ { content_type: :json, accept: :json }
85
+ end
86
+
87
+ # Authentication algorithm that is included in every request
88
+ #
89
+ # @param path [String] URL path of api
90
+ # @param params [Hash, NilClass] Api parameters
91
+ # @param method [String] Uppercase method for the request
92
+ # @return [Hash]
93
+ def generate_auth_headers( path:, params: nil, method: )
94
+ auth_timestamp = Time.now.to_i
95
+ auth_nonce = SecureRandom.hex( 16 )
96
+ auth_string = [@api_token, auth_timestamp, auth_nonce, method, path]
97
+ auth_string << JSON.generate( params, space: ' ' ) if params
98
+ auth_string = auth_string.join( '&' )
99
+ digest = OpenSSL::Digest.new( 'sha256' )
100
+ hmac = OpenSSL::HMAC.digest( digest, @api_secret, auth_string )
101
+ auth_signature = Base64.encode64( hmac ).chomp
102
+ {
103
+ auth_token: @api_token,
104
+ auth_timestamp: auth_timestamp,
105
+ auth_nonce: auth_nonce,
106
+ auth_signature: auth_signature
107
+ }
108
+ end
109
+
110
+ # Parse responses back from api server
111
+ #
112
+ # @param data [String]
113
+ # @return [Hash, Array, String]
114
+ def parse_data( data )
115
+ JSON.parse( data )
116
+ rescue JSON::ParserError => e
117
+ data
118
+ end
119
+
120
+ end
121
+ end
@@ -0,0 +1,45 @@
1
+ module PritunlApiClient
2
+
3
+ # Interact with /key api's
4
+ class Key
5
+
6
+ # @param api [PritunlApiClient::Api]
7
+ def initialize( api )
8
+ @api = api
9
+ end
10
+
11
+ # Download a users key tar archive
12
+ #
13
+ # @param organization_id [String]
14
+ # @param user_id [String]
15
+ # @param path [String] Local path to save downloaded file
16
+ # @return [String] Local path to downloaded file
17
+ def download_tar( organization_id:, user_id:, path: )
18
+ data = @api.get( "/key/#{organization_id}/#{user_id}.tar" )
19
+ File.write( path, data )
20
+ path
21
+ end
22
+
23
+ # Download a users onc key zip archive
24
+ #
25
+ # @param organization_id [String]
26
+ # @param user_id [String]
27
+ # @param path [String] Local path to save downloaded file
28
+ # @return [String] Local path to downloaded file
29
+ def download_zip( organization_id:, user_id:, path: )
30
+ data = @api.get( "/key_onc/#{organization_id}/#{user_id}.zip" )
31
+ File.write( path, data )
32
+ path
33
+ end
34
+
35
+ # Generate a temporary url to download a users key archive
36
+ #
37
+ # @param organization_id [String]
38
+ # @param user_id [String]
39
+ # @return [Hash]
40
+ def temporary_url( organization_id:, user_id: )
41
+ @api.get( "/key/#{organization_id}/#{user_id}" )
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,55 @@
1
+ module PritunlApiClient
2
+
3
+ # Interact with /organization api's
4
+ class Organization
5
+
6
+ # @param api [PritunlApiClient::Api]
7
+ def initialize( api )
8
+ @api = api
9
+ end
10
+
11
+ # Returns a list of organizations on the server
12
+ #
13
+ # @return [Array]
14
+ def all
15
+ @api.get( '/organization' )
16
+ end
17
+
18
+ # Returns an organization
19
+ #
20
+ # @param id [String] Organization ID
21
+ # @return [Hash]
22
+ def find( id )
23
+ @api.get( "/organization/#{id}" )
24
+ end
25
+
26
+ # Create a new organization
27
+ #
28
+ # @param params [Hash]
29
+ # @raise [ArgumentError] if params is not a Hash
30
+ # @return [Hash]
31
+ def create( params )
32
+ fail ArgumentError, 'params must be a Hash' unless params.is_a? Hash
33
+ @api.post( '/organization', params )
34
+ end
35
+
36
+ # Modify an existing organization
37
+ #
38
+ # @param id [String] Organization ID
39
+ # @param params [Hash]
40
+ # @raise [ArgumentError] if params is not a Hash
41
+ # @return [Hash]
42
+ def update( id, params )
43
+ fail ArgumentError, 'params must be a Hash' unless params.is_a? Hash
44
+ @api.put( "/organization/#{id}", params )
45
+ end
46
+
47
+ # Delete an existing organization
48
+ #
49
+ # @param id [String] Organization ID
50
+ def delete( id )
51
+ @api.delete( "/organization/#{id}" )
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,117 @@
1
+ module PritunlApiClient
2
+
3
+ # Interact with /server api's
4
+ class Server
5
+
6
+ # @param api [PritunlApiClient::Api]
7
+ def initialize( api )
8
+ @api = api
9
+ end
10
+
11
+ # Returns a list of servers
12
+ #
13
+ # @return [Array]
14
+ def all
15
+ @api.get( '/server' )
16
+ end
17
+
18
+ # Returns a server
19
+ #
20
+ # @param id [String] Server ID
21
+ # @return [Hash]
22
+ def find( id )
23
+ @api.get( "/server/#{id}" )
24
+ end
25
+
26
+ # Create a new server
27
+ #
28
+ # @param params [Hash]
29
+ # @raise [ArgumentError] if params is not a Hash
30
+ # @return [Hash]
31
+ def create( params )
32
+ fail ArgumentError, 'params must be a Hash' unless params.is_a? Hash
33
+ @api.post( '/server', params )
34
+ end
35
+
36
+ # Update an existing server
37
+ #
38
+ # @param id [String] Server ID
39
+ # @param params [Hash]
40
+ # @raise [ArgumentError] if params is not a Hash
41
+ # @return [Hash]
42
+ def update( id, params )
43
+ fail ArgumentError, 'params must be a Hash' unless params.is_a? Hash
44
+ @api.put( "/server/#{id}", params )
45
+ end
46
+
47
+ # Delete an existing server
48
+ #
49
+ # @param id [String] Server ID
50
+ def delete( id )
51
+ @api.delete( "/server/#{id}" )
52
+ end
53
+
54
+ # Start an existing server
55
+ #
56
+ # @param id [String] Server ID
57
+ # @return [Hash]
58
+ def start( id )
59
+ @api.put( "/server/#{id}/start" )
60
+ end
61
+
62
+ # Stop an existing server
63
+ #
64
+ # @param id [String] Server ID
65
+ # @return [Hash]
66
+ def stop( id )
67
+ @api.put( "/server/#{id}/stop" )
68
+ end
69
+
70
+ # Restart an existing server
71
+ #
72
+ # @param id [String] Server ID
73
+ # @return [Hash]
74
+ def restart( id )
75
+ @api.put( "/server/#{id}/restart" )
76
+ end
77
+
78
+ # Returns a list of organizations attached to a server
79
+ #
80
+ # @param id [String] Server ID
81
+ # @return [Array]
82
+ def organizations( id )
83
+ @api.get( "/server/#{id}/organization" )
84
+ end
85
+
86
+ # Attach an organization to an existing server
87
+ #
88
+ # @param id [String] Server ID
89
+ # @return [Hash]
90
+ def attach_organization( id, organization_id: )
91
+ @api.put( "/server/#{id}/organization/#{organization_id}" )
92
+ end
93
+
94
+ # Remove an organization from an existing server
95
+ #
96
+ # @param id [String] Server ID
97
+ def remove_organization( id, organization_id: )
98
+ @api.delete( "/server/#{id}/organization/#{organization_id}" )
99
+ end
100
+
101
+ # Get the output of a server
102
+ #
103
+ # @param id [String] Server ID
104
+ # @return [Hash]
105
+ def output( id )
106
+ @api.get( "/server/#{id}/output" )
107
+ end
108
+
109
+ # Clear the output of a server
110
+ #
111
+ # @param id [String] Server ID
112
+ def clear_output( id )
113
+ @api.delete( "/server/#{id}/output" )
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,29 @@
1
+ module PritunlApiClient
2
+
3
+ # Interact with /settings api's
4
+ class Settings
5
+
6
+ # @param api [PritunlApiClient::Api]
7
+ def initialize( api )
8
+ @api = api
9
+ end
10
+
11
+ # Get system settings
12
+ #
13
+ # @return [Array]
14
+ def all
15
+ @api.get( '/settings' )
16
+ end
17
+
18
+ # Change the system settings
19
+ #
20
+ # @param params [Hash]
21
+ # @raise [ArgumentError] if params is not a Hash
22
+ # @return [Hash]
23
+ def update( params )
24
+ fail ArgumentError, 'params must be a Hash' unless params.is_a? Hash
25
+ @api.put( '/settings', params )
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,73 @@
1
+ module PritunlApiClient
2
+
3
+ # Interact with /user api's
4
+ class User
5
+
6
+ # @param api [PritunlApiClient::Api]
7
+ def initialize( api )
8
+ @api = api
9
+ end
10
+
11
+ # Returns a list of users in an organization
12
+ #
13
+ # @param organization_id [String]
14
+ # @return [Array]
15
+ def all( organization_id: )
16
+ @api.get( "/user/#{organization_id}" )
17
+ end
18
+
19
+ # Returns a user from an organization
20
+ #
21
+ # @param id [String] User ID
22
+ # @param organization_id [String]
23
+ # @return [Hash]
24
+ def find( id, organization_id: )
25
+ @api.get( "/user/#{organization_id}/#{id}" )
26
+ end
27
+
28
+ # Create a new user in an organization. An array of users can be sent for bulk adding users
29
+ #
30
+ # @param params [Hash, Array]
31
+ # @raise [ArgumentError] if params is not a Hash or an Array
32
+ # @raise [ArgumentError] if organization_id is not passed into the parameter list
33
+ # @return [Hash, Array]
34
+ def create( params )
35
+ fail ArgumentError, 'params must be a Hash or an Array' unless ( params.is_a?( Hash ) || params.is_a?( Array ) )
36
+ fail ArgumentError, '"organization_id" is a required parameter' unless params.keys.include? :organization_id
37
+ organization_id = params.delete( :organization_id )
38
+ @api.post( "/user/#{organization_id}", params )
39
+ end
40
+
41
+ # Update an existing user in an organization
42
+ #
43
+ # @param id [String] User ID
44
+ # @param params [Hash]
45
+ # @raise [ArgumentError] if params is not a Hash
46
+ # @raise [ArgumentError] if organization_id is not passed into the parameter list
47
+ # @return [Hash]
48
+ def update( id, params )
49
+ fail ArgumentError, 'params must be a Hash' unless params.is_a? Hash
50
+ fail ArgumentError, '"organization_id" is a required parameter' unless params.keys.include? :organization_id
51
+ organization_id = params.delete( :organization_id )
52
+ @api.put( "/user/#{organization_id}/#{id}", params )
53
+ end
54
+
55
+ # Delete an existing user in an organization, this will disconnect the user
56
+ #
57
+ # @param id [String] User ID
58
+ # @param organization_id [String]
59
+ def delete( id, organization_id: )
60
+ @api.delete( "/user/#{organization_id}/#{id}" )
61
+ end
62
+
63
+ # Generate a new two-step authentication secret for an existing user
64
+ #
65
+ # @param id [String] User ID
66
+ # @param organization_id [String]
67
+ # @return [Hash]
68
+ def otp_secret( id, organization_id: )
69
+ @api.put( "/user/#{organization_id}/#{id}/otp_secret" )
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ module PritunlApiClient
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path( '../lib', __FILE__ )
3
+ $LOAD_PATH.unshift( lib ) unless $LOAD_PATH.include?( lib )
4
+ require 'pritunl_api_client/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'pritunl_api_client'
8
+ spec.version = PritunlApiClient::VERSION
9
+ spec.authors = ['Eric Terry']
10
+ spec.email = ['eterry1388@aol.com']
11
+
12
+ spec.summary = 'Pritunl Ruby API Client'
13
+ spec.description = 'API client for Pritunl written in Ruby'
14
+ spec.homepage = 'http://eterry1388.github.io/pritunl_api_client'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split( "\x0" ).reject { |f| f.match( %r{^(test|spec|features)/} ) }
18
+ spec.executables = spec.files.grep( %r{^bin/} ) { |f| File.basename( f ) }
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.required_ruby_version = '>= 2.1.0'
22
+
23
+ spec.add_dependency 'rest-client'
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.10'
26
+ spec.add_development_dependency 'rake', '~> 10.0'
27
+ spec.add_development_dependency 'rspec', '~> 3.3'
28
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pritunl_api_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Eric Terry
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rest-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.3'
69
+ description: API client for Pritunl written in Ruby
70
+ email:
71
+ - eterry1388@aol.com
72
+ executables:
73
+ - console
74
+ - setup
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - ".rspec"
80
+ - Gemfile
81
+ - LICENSE
82
+ - README.md
83
+ - Rakefile
84
+ - bin/console
85
+ - bin/setup
86
+ - lib/pritunl_api_client.rb
87
+ - lib/pritunl_api_client/api.rb
88
+ - lib/pritunl_api_client/key.rb
89
+ - lib/pritunl_api_client/organization.rb
90
+ - lib/pritunl_api_client/server.rb
91
+ - lib/pritunl_api_client/settings.rb
92
+ - lib/pritunl_api_client/user.rb
93
+ - lib/pritunl_api_client/version.rb
94
+ - pritunl_api_client.gemspec
95
+ homepage: http://eterry1388.github.io/pritunl_api_client
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: 2.1.0
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 2.4.8
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: Pritunl Ruby API Client
119
+ test_files: []