ninjaone 0.2.0 → 0.3.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 +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +132 -64
- data/lib/ninjaone/client/backup.rb +2 -24
- data/lib/ninjaone/client/devices.rb +6 -40
- data/lib/ninjaone/client/organizations.rb +11 -30
- data/lib/ninjaone/client/queries.rb +35 -0
- data/lib/ninjaone/client/system.rb +24 -22
- data/lib/ninjaone/client/users.rb +15 -0
- data/lib/ninjaone/client.rb +34 -15
- data/lib/ninjaone/cursor_pagination.rb +85 -0
- data/lib/ninjaone/version.rb +1 -1
- data/lib/ninjaone.rb +5 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 14e3e9d7389ec68d56ab1289d050a76c4287c223dec960df4201f236c7d24632
|
|
4
|
+
data.tar.gz: b78f6990641e9782d5033f9b2c4940fcb8e0464ba8c89ab01c7905bd54aca54e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6ae0f84a5385fcff884d4de3830c9089bca742d8f8f8ba641e41d91231bb365cb9b800cb391ca7da2729c7be7bbbb265975dbbae11101b5bc74f69907ab828d0
|
|
7
|
+
data.tar.gz: df9bff698081312e3c1d11f4b319f554f3d091f02c34c5ad23eb20d4793f00883dec12269d55c3e3ec072ef5a4499263f8faea2b535c1ddcbe93fa4a88849824
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
This is a wrapper for the ninjaone API.
|
|
6
6
|
You can see the [API endpoints](https://app.ninjarmm.com/apidocs/)
|
|
7
7
|
|
|
8
|
-
Currently only the GET requests to endpoints
|
|
8
|
+
Currently only the GET requests to endpoints
|
|
9
9
|
are implemented (readonly).
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
@@ -66,100 +66,168 @@ client.login
|
|
|
66
66
|
|
|
67
67
|
|Resource|API endpoint|
|
|
68
68
|
|:--|:--|
|
|
69
|
-
|
|
69
|
+
|`login`|https://app.ninjarmm.com/apidocs/?links.active=authorization|
|
|
70
70
|
|
|
71
71
|
### System
|
|
72
72
|
|
|
73
73
|
Core system Entities and Resources
|
|
74
74
|
|
|
75
75
|
```ruby
|
|
76
|
-
|
|
76
|
+
client.organizations
|
|
77
|
+
client.devices
|
|
78
|
+
client.contacts
|
|
77
79
|
```
|
|
78
80
|
|
|
79
|
-
|
|
|
81
|
+
|Method|Description|
|
|
80
82
|
|:--|:--|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
83
|
+
|`contacts(params = {})`|List all contacts|
|
|
84
|
+
|`contact(id, params = {})`|Retrieve a specific contact by ID|
|
|
85
|
+
|`organizations(params = {})`|List all organizations|
|
|
86
|
+
|`organization(id, params = {})`|Retrieve a specific organization by ID|
|
|
87
|
+
|`organizations_detailed(params = {})`|List all organizations with detailed information|
|
|
88
|
+
|`policies(params = {})`|List all policies|
|
|
89
|
+
|`jobs(params = {})`|List all active jobs|
|
|
90
|
+
|`activities(params = {})`|List all activities|
|
|
91
|
+
|`alerts(params = {})`|List all active alerts (triggered conditions)|
|
|
92
|
+
|`automation_scripts(params = {})`|List available automation scripts|
|
|
93
|
+
|`devices(params = {})`|List all devices|
|
|
94
|
+
|`devices_detailed(params = {})`|List all devices with detailed information|
|
|
95
|
+
|`notification_channels_enabled(params = {})`|List enabled notification channels|
|
|
96
|
+
|`notification_channels(params = {})`|List all notification channels|
|
|
97
|
+
|`groups(params = {})`|List all groups (saved searches)|
|
|
98
|
+
|`locations(params = {})`|List all locations|
|
|
99
|
+
|`roles(params = {})`|List device roles|
|
|
100
|
+
|`tasks(params = {})`|List scheduled tasks|
|
|
101
|
+
|`software_products(params = {})`|List supported 3rd party software|
|
|
102
|
+
|`users(params = {})`|List all users|
|
|
103
|
+
|`user_end_users(params = {})`|List end users|
|
|
104
|
+
|`user_technicians(params = {})`|List technicians|
|
|
105
|
+
|`user_roles(params = {})`|Get user roles|
|
|
106
|
+
|`devices_search(params = {})`|Search devices by query parameter `q`|
|
|
107
|
+
|`search_devices(query_string, options = {})`|Helper method to search devices (equivalent to `devices_search({q: query_string})`)|
|
|
104
108
|
|
|
105
109
|
### Organizations
|
|
106
110
|
|
|
107
|
-
All
|
|
111
|
+
All APIs related to organizations
|
|
108
112
|
|
|
109
113
|
```ruby
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
114
|
+
organizations = client.organizations
|
|
115
|
+
org_id = organizations.first.id
|
|
116
|
+
org_devices = client.organization_devices(org_id)
|
|
113
117
|
```
|
|
114
118
|
|
|
115
|
-
|
|
|
119
|
+
|Method|Description|
|
|
116
120
|
|:--|:--|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
|`organization(id, params = {})`|Retrieve a specific organization by ID|
|
|
122
|
+
|`organization_locations(id, params = {})`|List all locations for the specified organization|
|
|
123
|
+
|`organization_end_users(id, params = {})`|List all end users in the specified organization|
|
|
124
|
+
|`organization_custom_fields(id, params = {})`|Retrieve custom fields for the specified organization|
|
|
125
|
+
|`organization_devices(id, params = {})`|List all devices in the specified organization|
|
|
126
|
+
|`organization_locations_backup_usage(id, params = {})`|Retrieve backup usage for all locations in the specified organization|
|
|
127
|
+
|`organization_backup_usage_by_location(id, location_id, params = {})`|Retrieve backup usage for a specific location in the specified organization|
|
|
128
|
+
|`organization_location_custom_fields(id, location_id, params = {})`|Retrieve custom fields for a specific location in the specified organization|
|
|
124
129
|
|
|
125
130
|
### Backup
|
|
126
131
|
|
|
127
|
-
All
|
|
132
|
+
All APIs related to backup
|
|
128
133
|
|
|
129
134
|
```ruby
|
|
130
|
-
#
|
|
131
|
-
failed_jobs = client.backup_jobs(sf:'status = FAILED')
|
|
135
|
+
# Get failed jobs using status filter
|
|
136
|
+
failed_jobs = client.backup_jobs(sf: 'status = FAILED')
|
|
137
|
+
integrity_jobs = client.backup_integrity_checks_jobs
|
|
132
138
|
```
|
|
133
139
|
|
|
134
|
-
|
|
|
140
|
+
|Method|Description|
|
|
135
141
|
|:--|:--|
|
|
136
|
-
|`backup_jobs(params)`|
|
|
137
|
-
|`
|
|
142
|
+
|`backup_jobs(params = {})`|List all backup jobs. Supports filtering via `sf` (filter) and `sc` (sort) parameters|
|
|
143
|
+
|`backup_integrity_checks_jobs(params = {})`|List all backup integrity check jobs. Supports filtering and sorting parameters|
|
|
138
144
|
|
|
139
145
|
### Devices
|
|
140
146
|
|
|
141
|
-
All
|
|
147
|
+
All APIs related to devices
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
device = client.device(12345)
|
|
151
|
+
device_jobs = client.device_jobs(12345)
|
|
152
|
+
device_activities = client.device_activities(12345, since: '2026-01-01T00:00:00Z')
|
|
153
|
+
group_device_ids = client.group_device_ids(group_id)
|
|
154
|
+
```
|
|
142
155
|
|
|
143
|
-
|
|
|
156
|
+
|Method|Description|
|
|
144
157
|
|:--|:--|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
|`device(id, params = {})`|Retrieve details of a single device by its device ID|
|
|
159
|
+
|`device_policy_overrides(id, params = {})`|Retrieve policy overrides applied to the specified device|
|
|
160
|
+
|`device_jobs(id, params = {})`|Retrieve all jobs associated with the specified device|
|
|
161
|
+
|`device_activities(id, params = {})`|Retrieve activities for the specified device (supports `since` filtering)|
|
|
162
|
+
|`device_alerts(id, params = {})`|Retrieve alerts related to the specified device|
|
|
163
|
+
|`device_disks(id, params = {})`|Retrieve disk information for the specified device|
|
|
164
|
+
|`device_processors(id, params = {})`|Retrieve processor information for the specified device|
|
|
165
|
+
|`device_software(id, params = {})`|Retrieve installed software for the specified device|
|
|
166
|
+
|`device_volumes(id, params = {})`|Retrieve volume information for the specified device|
|
|
167
|
+
|`device_windows_services(id, params = {})`|Retrieve Windows services for the specified device|
|
|
168
|
+
|`device_custom_fields(id, params = {})`|Retrieve custom fields associated with the specified device|
|
|
169
|
+
|`device_os_patch_installs(id, params = {})`|Retrieve operating system patch installation records for the specified device|
|
|
170
|
+
|`device_software_patch_installs(id, params = {})`|Retrieve software patch installation records for the specified device|
|
|
171
|
+
|`device_last_logged_on_user(id, params = {})`|Retrieve information about the last logged-on user of the device|
|
|
172
|
+
|`device_network_interfaces(id, params = {})`|Retrieve network interface information for the specified device|
|
|
173
|
+
|`device_os_patches(id, params = {})`|Retrieve available or installed operating system patches for the device|
|
|
174
|
+
|`device_software_patches(id, params = {})`|Retrieve available or installed software patches for the device|
|
|
175
|
+
|`group_device_ids(id, params = {})`|Retrieve device IDs for all devices in the specified group|
|
|
176
|
+
|
|
177
|
+
### Users
|
|
178
|
+
|
|
179
|
+
All APIs related to user management
|
|
180
|
+
|
|
181
|
+
```ruby
|
|
182
|
+
end_user = client.user_end_user(end_user_id)
|
|
183
|
+
end_user_custom_fields = client.user_end_user_custom_fields(end_user_id)
|
|
184
|
+
technician = client.user_technician(technician_id)
|
|
185
|
+
```
|
|
162
186
|
|
|
187
|
+
|Method|Description|
|
|
188
|
+
|:--|:--|
|
|
189
|
+
|`user_end_user(id, params = {})`|Retrieve details of a specific end user|
|
|
190
|
+
|`user_end_user_custom_fields(id, params = {})`|Retrieve custom fields for a specific end user|
|
|
191
|
+
|`user_technician(id, params = {})`|Retrieve details of a specific technician|
|
|
192
|
+
|
|
193
|
+
### Queries
|
|
194
|
+
|
|
195
|
+
Query endpoints that support pagination for advanced data retrieval
|
|
196
|
+
|
|
197
|
+
```ruby
|
|
198
|
+
av_status = client.queries_antivirus_status
|
|
199
|
+
device_health = client.queries_device_health
|
|
200
|
+
software_list = client.queries_software
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
All query methods support pagination and filtering parameters. Query methods return paginated results.
|
|
204
|
+
|
|
205
|
+
|Method|Description|
|
|
206
|
+
|:--|:--|
|
|
207
|
+
|`queries_antivirus_status(params = {})`|Query antivirus status across devices|
|
|
208
|
+
|`queries_antivirus_threats(params = {})`|Query antivirus threats across devices|
|
|
209
|
+
|`queries_computer_systems(params = {})`|Query computer system information|
|
|
210
|
+
|`queries_custom_fields_detailed(params = {})`|Query custom fields with detailed information|
|
|
211
|
+
|`queries_custom_fields(params = {})`|Query custom fields|
|
|
212
|
+
|`queries_device_health(params = {})`|Query device health status|
|
|
213
|
+
|`queries_backup_usage(params = {})`|Query backup usage across devices|
|
|
214
|
+
|`queries_disks(params = {})`|Query disk information|
|
|
215
|
+
|`queries_os_patch_installs(params = {})`|Query operating system patch installations|
|
|
216
|
+
|`queries_software_patch_installs(params = {})`|Query software patch installations|
|
|
217
|
+
|`queries_logged_on_users(params = {})`|Query currently logged-on users|
|
|
218
|
+
|`queries_network_interfaces(params = {})`|Query network interface information|
|
|
219
|
+
|`queries_operating_systems(params = {})`|Query operating system information|
|
|
220
|
+
|`queries_os_patches(params = {})`|Query operating system patches|
|
|
221
|
+
|`queries_software_patches(params = {})`|Query software patches|
|
|
222
|
+
|`queries_policy_overrides(params = {})`|Query policy overrides|
|
|
223
|
+
|`queries_processors(params = {})`|Query processor information|
|
|
224
|
+
|`queries_raid_controllers(params = {})`|Query RAID controller information|
|
|
225
|
+
|`queries_raid_drives(params = {})`|Query RAID drive information|
|
|
226
|
+
|`queries_scoped_custom_fields_detailed(params = {})`|Query scoped custom fields with detailed information|
|
|
227
|
+
|`queries_scoped_custom_fields(params = {})`|Query scoped custom fields|
|
|
228
|
+
|`queries_software(params = {})`|Query software information|
|
|
229
|
+
|`queries_volumes(params = {})`|Query volume information|
|
|
230
|
+
|`queries_windows_services(params = {})`|Query Windows services|
|
|
163
231
|
|
|
164
232
|
## Contributing
|
|
165
233
|
|
|
@@ -6,32 +6,10 @@ module NinjaOne
|
|
|
6
6
|
#
|
|
7
7
|
# @see https://app.ninjarmm.com/apidocs/?links.active=core#/Backup Ninja One Developer Documentation - Backup section
|
|
8
8
|
module Backup
|
|
9
|
-
# Dynamically defines methods for interacting with NinjaOne API resources.
|
|
10
|
-
#
|
|
11
|
-
# Depending on the arguments, this will define methods to:
|
|
12
|
-
# - Fetch all records for a resource
|
|
13
|
-
# - Fetch a specific record by ID
|
|
14
|
-
#
|
|
15
|
-
# @param method [Symbol] The method name for fetching all records.
|
|
16
|
-
# @param path [String] The API path for the resource. Defaults to the method name.
|
|
17
|
-
#
|
|
18
|
-
# @example Defining endpoints
|
|
19
|
-
# api_endpoint :companies, :company
|
|
20
|
-
# # Defines:
|
|
21
|
-
# # - `companies(params = {})` to fetch all companies.
|
|
22
|
-
# # - `company(id, params = {})` to fetch a single company by ID.
|
|
23
|
-
def self.backup_endpoint(method, path = method.to_s.tr('_', '-'))
|
|
24
|
-
# Define method to fetch all records
|
|
25
|
-
send(:define_method, method) do |params = {}|
|
|
26
|
-
results = get(api_url(path), params)
|
|
27
|
-
results.results
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
9
|
|
|
31
10
|
# Backup endpoints (GET)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
11
|
+
Client::define_endpoint('backup/jobs', nil, true)
|
|
12
|
+
Client::define_endpoint('backup/integrity-check-jobs', nil, true)
|
|
35
13
|
end
|
|
36
14
|
end
|
|
37
15
|
end
|
|
@@ -2,47 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
module NinjaOne
|
|
4
4
|
class Client
|
|
5
|
-
# Contains Device
|
|
5
|
+
# Contains Device and group related API calls for Ninja One.
|
|
6
6
|
#
|
|
7
7
|
# @see https://app.ninjarmm.com/apidocs/?links.active=core#/Devices Ninja One Developer Documentation - Device section
|
|
8
8
|
module Devices
|
|
9
|
-
# Defines a device-specific API endpoint method dynamically.
|
|
10
|
-
#
|
|
11
|
-
# This helper creates instance methods in the form of:
|
|
12
|
-
# device_<method>(id, params = {})
|
|
13
|
-
#
|
|
14
|
-
# Example:
|
|
15
|
-
# device_endpoint(:jobs)
|
|
16
|
-
# # => defines #device_jobs(id, params = {})
|
|
17
|
-
#
|
|
18
|
-
# @param method [Symbol]
|
|
19
|
-
# The method name suffix to generate (e.g., :jobs, :alerts).
|
|
20
|
-
#
|
|
21
|
-
# @param path [String]
|
|
22
|
-
# The API path segment. Defaults to the method name with
|
|
23
|
-
# underscores replaced by hyphens.
|
|
24
|
-
#
|
|
25
|
-
# @return [void]
|
|
26
|
-
def self.device_endpoint(method, path = method.to_s.tr('_', '-'))
|
|
27
|
-
# Define method to fetch all records for device
|
|
28
|
-
send(:define_method, "device_#{method}") do |id, params = {}|
|
|
29
|
-
get(api_url("device/#{id}/#{path}"), params)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
9
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
# The NinjaOne device ID.
|
|
37
|
-
#
|
|
38
|
-
# @param params [Hash, nil]
|
|
39
|
-
# Optional query parameters.
|
|
40
|
-
#
|
|
41
|
-
# @return [Hash]
|
|
42
|
-
# The device details returned by the API.
|
|
43
|
-
def device(id, params = nil)
|
|
44
|
-
get(api_url("device/#{id}"), params)
|
|
45
|
-
end
|
|
10
|
+
Client::define_endpoint(:device, '')
|
|
11
|
+
Client::define_endpoint(:device, 'policy/overrides')
|
|
12
|
+
Client::define_endpoint(:group, 'device-ids')
|
|
46
13
|
|
|
47
14
|
# Device-related GET endpoints.
|
|
48
15
|
#
|
|
@@ -54,10 +21,9 @@ module NinjaOne
|
|
|
54
21
|
# device_activities(123, since: '2026-01-01T00:00:00Z')
|
|
55
22
|
#
|
|
56
23
|
[:jobs, :activities, :alerts, :disks, :processors, :software, :volumes, :windows_services, :custom_fields,
|
|
57
|
-
:os_patch_installs, :software_patch_installs, :last_logged_on_user, :network_interfaces, :os_patches, :software_patches].each do |
|
|
58
|
-
|
|
24
|
+
:os_patch_installs, :software_patch_installs, :last_logged_on_user, :network_interfaces, :os_patches, :software_patches].each do |resource|
|
|
25
|
+
Client::define_endpoint(:device, resource.to_s.gsub('_','-'))
|
|
59
26
|
end
|
|
60
|
-
device_endpoint(:policy_overrides, 'policy/overrides')
|
|
61
27
|
end
|
|
62
28
|
end
|
|
63
29
|
end
|
|
@@ -2,47 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
module NinjaOne
|
|
4
4
|
class Client
|
|
5
|
-
# Contains Organizations API calls for Ninja One.
|
|
5
|
+
# Contains Organizations and location API calls for Ninja One.
|
|
6
6
|
#
|
|
7
7
|
# @see https://app.ninjarmm.com/apidocs/?links.active=core#/organization Ninja One Developer Documentation
|
|
8
8
|
module Organizations
|
|
9
|
-
# Dynamically defines methods for interacting with NinjaOne API resources.
|
|
10
|
-
#
|
|
11
|
-
# Depending on the arguments, this will define methods to:
|
|
12
|
-
# - Fetch all records for a resource
|
|
13
|
-
# - Fetch a specific record by ID
|
|
14
|
-
#
|
|
15
|
-
# @param method [Symbol] The method name for fetching all records.
|
|
16
|
-
# @param singular_method [Symbol, nil] The method name for fetching a single record by ID. Optional.
|
|
17
|
-
# @param path [String] The API path for the resource. Defaults to the method name.
|
|
18
|
-
#
|
|
19
|
-
# @example Defining endpoints
|
|
20
|
-
# api_endpoint :companies, :company
|
|
21
|
-
# # Defines:
|
|
22
|
-
# # - `companies(params = {})` to fetch all companies.
|
|
23
|
-
# # - `company(id, params = {})` to fetch a single company by ID.
|
|
24
|
-
def self.api_endpoint_suffix(method, suffix)
|
|
25
|
-
# Define method to fetch a single record by ID
|
|
26
|
-
name = "#{method}_#{suffix.gsub(/[-\/]/,'_')}"
|
|
27
9
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
api_endpoint_suffix(:organization, 'locations')
|
|
34
|
-
api_endpoint_suffix(:organization, 'end-users')
|
|
35
|
-
api_endpoint_suffix(:organization, 'custom-fields')
|
|
36
|
-
api_endpoint_suffix(:organization, 'devices')
|
|
37
|
-
api_endpoint_suffix(:organization, 'locations/backup/usage')
|
|
10
|
+
Client::define_endpoint(:organization, 'locations')
|
|
11
|
+
Client::define_endpoint(:organization, 'end-users')
|
|
12
|
+
Client::define_endpoint(:organization, 'custom-fields')
|
|
13
|
+
Client::define_endpoint(:organization, 'devices')
|
|
14
|
+
Client::define_endpoint(:organization, 'locations/backup/usage')
|
|
38
15
|
|
|
39
16
|
# Returns a location backup usage
|
|
40
17
|
def organization_backup_usage_by_location(id, location_id, params={})
|
|
41
18
|
get(api_url("organization/#{id}/locations/#{location_id}/backup/usage"), params)
|
|
42
19
|
rescue Faraday::ServerError
|
|
43
|
-
# it looks like a server error is thrown when no backup is available; fake it by returning
|
|
20
|
+
# it looks like a server error is thrown when no backup is available; fake it by returning an empty array
|
|
44
21
|
[]
|
|
45
22
|
end
|
|
23
|
+
# Returns custom fields for an organization location
|
|
24
|
+
def organization_location_custom_fields(id, location_id, params={})
|
|
25
|
+
get(api_url("organization/#{id}/location/#{location_id}/custom-fields"), params)
|
|
26
|
+
end
|
|
46
27
|
end
|
|
47
28
|
end
|
|
48
29
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NinjaOne
|
|
4
|
+
class Client
|
|
5
|
+
# Contains Queries API calls for Ninja One.
|
|
6
|
+
#
|
|
7
|
+
# @see https://app.ninjarmm.com/apidocs/?links.active=core#/queries Ninja One Developer Documentation
|
|
8
|
+
module Queries
|
|
9
|
+
Client::define_endpoint('queries/antivirus-status', nil, true)
|
|
10
|
+
Client::define_endpoint('queries/antivirus-threats', nil, true)
|
|
11
|
+
Client::define_endpoint('queries/computer-systems', nil, true)
|
|
12
|
+
Client::define_endpoint('queries/custom-fields-detailed', nil, true)
|
|
13
|
+
Client::define_endpoint('queries/custom-fields', nil, true)
|
|
14
|
+
Client::define_endpoint('queries/device-health', nil, true)
|
|
15
|
+
Client::define_endpoint('queries/backup/usage', nil, true)
|
|
16
|
+
Client::define_endpoint('queries/disks', nil, true)
|
|
17
|
+
Client::define_endpoint('queries/os-patch-installs', nil, true)
|
|
18
|
+
Client::define_endpoint('queries/software-patch-installs', nil, true)
|
|
19
|
+
Client::define_endpoint('queries/logged-on-users', nil, true)
|
|
20
|
+
Client::define_endpoint('queries/network-interfaces', nil, true)
|
|
21
|
+
Client::define_endpoint('queries/operating-systems', nil, true)
|
|
22
|
+
Client::define_endpoint('queries/os-patches', nil, true)
|
|
23
|
+
Client::define_endpoint('queries/software-patches', nil, true)
|
|
24
|
+
Client::define_endpoint('queries/policy-overrides', nil, true)
|
|
25
|
+
Client::define_endpoint('queries/processors', nil, true)
|
|
26
|
+
Client::define_endpoint('queries/raid-controllers', nil, true)
|
|
27
|
+
Client::define_endpoint('queries/raid-drives', nil, true)
|
|
28
|
+
Client::define_endpoint('queries/scoped-custom-fields-detailed', nil, true)
|
|
29
|
+
Client::define_endpoint('queries/scoped-custom-fields', nil, true)
|
|
30
|
+
Client::define_endpoint('queries/software', nil, true)
|
|
31
|
+
Client::define_endpoint('queries/volumes', nil, true)
|
|
32
|
+
Client::define_endpoint('queries/windows-services', nil, true)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -7,28 +7,30 @@ module NinjaOne
|
|
|
7
7
|
# @see https://app.ninjarmm.com/apidocs/?links.active=core#/system Ninja One Developer Documentation
|
|
8
8
|
module System
|
|
9
9
|
|
|
10
|
-
Client::
|
|
11
|
-
Client::
|
|
12
|
-
Client::
|
|
13
|
-
Client::
|
|
14
|
-
Client::
|
|
15
|
-
Client::
|
|
16
|
-
Client::
|
|
17
|
-
Client::
|
|
18
|
-
Client::
|
|
19
|
-
Client::
|
|
20
|
-
Client::
|
|
21
|
-
Client::
|
|
22
|
-
Client::
|
|
23
|
-
Client::
|
|
24
|
-
Client::
|
|
25
|
-
Client::
|
|
26
|
-
Client::
|
|
27
|
-
Client::
|
|
28
|
-
Client::
|
|
29
|
-
Client::
|
|
30
|
-
Client::
|
|
31
|
-
Client::
|
|
10
|
+
Client::define_endpoint(:contacts)
|
|
11
|
+
Client::define_endpoint(:contact, '')
|
|
12
|
+
Client::define_endpoint(:organizations)
|
|
13
|
+
Client::define_endpoint(:organization, '')
|
|
14
|
+
Client::define_endpoint('organizations-detailed')
|
|
15
|
+
Client::define_endpoint(:policies)
|
|
16
|
+
Client::define_endpoint(:jobs)
|
|
17
|
+
Client::define_endpoint(:activities)
|
|
18
|
+
Client::define_endpoint(:alerts)
|
|
19
|
+
Client::define_endpoint('automation/scripts')
|
|
20
|
+
Client::define_endpoint(:devices)
|
|
21
|
+
Client::define_endpoint('devices-detailed')
|
|
22
|
+
Client::define_endpoint('notification-channels/enabled')
|
|
23
|
+
Client::define_endpoint('notification-channels')
|
|
24
|
+
Client::define_endpoint(:groups)
|
|
25
|
+
Client::define_endpoint(:locations)
|
|
26
|
+
Client::define_endpoint(:roles)
|
|
27
|
+
Client::define_endpoint(:tasks)
|
|
28
|
+
Client::define_endpoint('software-products')
|
|
29
|
+
Client::define_endpoint(:users)
|
|
30
|
+
Client::define_endpoint('user/end-users')
|
|
31
|
+
Client::define_endpoint('user/roles')
|
|
32
|
+
Client::define_endpoint('user/technicians')
|
|
33
|
+
Client::define_endpoint('devices/search')
|
|
32
34
|
|
|
33
35
|
def search_devices(query_string, options={})
|
|
34
36
|
devices_search(options.merge({q:query_string}))
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NinjaOne
|
|
4
|
+
class Client
|
|
5
|
+
# Contains Organizations API calls for Ninja One.
|
|
6
|
+
#
|
|
7
|
+
# @see https://app.ninjarmm.com/apidocs/?links.active=core#/users Ninja One Developer Documentation
|
|
8
|
+
module Users
|
|
9
|
+
|
|
10
|
+
Client::define_endpoint('user/end-user', '')
|
|
11
|
+
Client::define_endpoint('user/end-user', 'custom-fields')
|
|
12
|
+
Client::define_endpoint('user/technician', '')
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/ninjaone/client.rb
CHANGED
|
@@ -9,34 +9,52 @@ module NinjaOne
|
|
|
9
9
|
# @note All methods are grouped in separate modules for better organization and follow the structure provided in the official API documentation.
|
|
10
10
|
# @see https://developers.skykick.com/Guides/Authentication
|
|
11
11
|
class Client < API
|
|
12
|
+
|
|
13
|
+
# Constructs url resource name from url path
|
|
14
|
+
#
|
|
15
|
+
# @param path [String] Resource name
|
|
16
|
+
# @return [String] translated from /- to _
|
|
17
|
+
def self.resource_to_name(path)
|
|
18
|
+
path.to_s.gsub(/[-\/]/,'_')
|
|
19
|
+
end
|
|
20
|
+
|
|
12
21
|
# Dynamically defines methods for interacting with NinjaOne API resources.
|
|
13
22
|
#
|
|
14
23
|
# Depending on the arguments, this will define methods to:
|
|
15
|
-
# - Fetch all records for
|
|
16
|
-
# - Fetch a specific record by ID
|
|
24
|
+
# - Fetch all records for the given scope
|
|
25
|
+
# - Fetch a resource specific record by ID
|
|
26
|
+
#
|
|
27
|
+
# @param scope [Symbol] The method name for fetching all records.
|
|
28
|
+
# @param resource [String] If given, fetches all records for scope by id. If empty string, it will load single scope record
|
|
17
29
|
#
|
|
18
|
-
#
|
|
19
|
-
# @param singular_method [Symbol, nil] The method name for fetching a single record by ID. Optional.
|
|
20
|
-
# @param path [String] The API path for the resource. Defaults to the method name.
|
|
30
|
+
# Paging is not supported.
|
|
21
31
|
#
|
|
22
32
|
# @example Defining endpoints
|
|
23
33
|
# api_endpoint :companies, :company
|
|
24
34
|
# # Defines:
|
|
25
35
|
# # - `companies(params = {})` to fetch all companies.
|
|
26
36
|
# # - `company(id, params = {})` to fetch a single company by ID.
|
|
27
|
-
def self.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
send(:define_method,
|
|
35
|
-
|
|
37
|
+
def self.define_endpoint(scope, resource = nil, paged = false)
|
|
38
|
+
if resource
|
|
39
|
+
name = self.resource_to_name(scope)
|
|
40
|
+
name = "#{name}_#{self.resource_to_name(resource)}" if resource && !resource.empty?
|
|
41
|
+
# change to nil if resource is empty so we ar eable to generate /scope/id/resource
|
|
42
|
+
# but also /scope/id without training /
|
|
43
|
+
resource = resource&.empty? ? nil : resource
|
|
44
|
+
send(:define_method, name) do |id, params = {}|
|
|
45
|
+
url = api_url([scope, id, resource].compact.join('/'))
|
|
46
|
+
paged ? get_paged(url, params) : get(url, params)
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
name = self.resource_to_name(scope)
|
|
50
|
+
send(:define_method, name) do |params = {}|
|
|
51
|
+
url = api_url(scope)
|
|
52
|
+
paged ? get_paged(url, params) : get(url, params)
|
|
36
53
|
end
|
|
37
54
|
end
|
|
38
55
|
end
|
|
39
56
|
|
|
57
|
+
|
|
40
58
|
# Dynamically require all files in the `client` directory.
|
|
41
59
|
# This will load additional API modules as separate files for better modularity and code organization.
|
|
42
60
|
Dir[File.expand_path('client/*.rb', __dir__)].each { |f| require f }
|
|
@@ -48,6 +66,8 @@ module NinjaOne
|
|
|
48
66
|
include NinjaOne::Client::Organizations
|
|
49
67
|
include NinjaOne::Client::Backup
|
|
50
68
|
include NinjaOne::Client::Devices
|
|
69
|
+
include NinjaOne::Client::Users
|
|
70
|
+
include NinjaOne::Client::Queries
|
|
51
71
|
|
|
52
72
|
# Constructs the full API URL for a given path.
|
|
53
73
|
#
|
|
@@ -56,6 +76,5 @@ module NinjaOne
|
|
|
56
76
|
def api_url(path)
|
|
57
77
|
"/v2/#{path}"
|
|
58
78
|
end
|
|
59
|
-
|
|
60
79
|
end
|
|
61
80
|
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'uri'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module NinjaOne
|
|
7
|
+
# Defines HTTP request pagination methods for NinjOne API.
|
|
8
|
+
# This module handles the pagination strategy required when dealing with paginated
|
|
9
|
+
# API results. NinjaOne uses Cursor pagination, in combination with `cursor` and `pageSize` parameter
|
|
10
|
+
module RequestPagination
|
|
11
|
+
# Maintains pagination state for cursor-based endpoints.
|
|
12
|
+
#
|
|
13
|
+
# NinjaOne returns payloads like:
|
|
14
|
+
# {
|
|
15
|
+
# "cursor": { "name": "string", "offset": 0, "count": 0, "expires": 0 },
|
|
16
|
+
# "results": []
|
|
17
|
+
# }
|
|
18
|
+
#
|
|
19
|
+
# @example Pagination Initialization
|
|
20
|
+
# paginator = NinjaOne::RequestPagination::CursorPagination.new(100)
|
|
21
|
+
# options = paginator.page_options # => { pageSize: 100 }
|
|
22
|
+
#
|
|
23
|
+
# @see https://app.ninjarmm.com/apidocs/?links.active=core#/queries/getAntivirusStatusReport
|
|
24
|
+
class CursorPagination
|
|
25
|
+
attr_reader :offset, :limit, :total
|
|
26
|
+
|
|
27
|
+
# Initializes the pagination object with the specified page size.
|
|
28
|
+
# Assumes that pagination starts at the first page (offset 0).
|
|
29
|
+
#
|
|
30
|
+
# @param page_size [Integer] Number of results per page
|
|
31
|
+
def initialize(page_size)
|
|
32
|
+
@offset = 0
|
|
33
|
+
@cursor = nil
|
|
34
|
+
@limit = page_size
|
|
35
|
+
# Assume at least one page initially (used to short-circuit more_pages? after last page)
|
|
36
|
+
@total = @limit
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns the pagination options to be sent as query parameters.
|
|
40
|
+
# If a cursor is present, it will be included to fetch the next page.
|
|
41
|
+
#
|
|
42
|
+
# @return [Hash<Symbol, Integer|String>] Query parameters for pagination
|
|
43
|
+
def page_options
|
|
44
|
+
{
|
|
45
|
+
pageSize: @limit,
|
|
46
|
+
cursor: @cursor
|
|
47
|
+
}.compact
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Updates the pagination state for the next page based on the current page's data.
|
|
51
|
+
# The NinjaOne API does not allow skipping
|
|
52
|
+
#
|
|
53
|
+
# @param data [Hash] The data from the current page
|
|
54
|
+
def next_page!(data)
|
|
55
|
+
# Update the total number of results based on the size of the current data set.
|
|
56
|
+
if cursor = data['cursor']
|
|
57
|
+
@total = cursor['count']
|
|
58
|
+
@offset = cursor['offset']
|
|
59
|
+
@cursor = cursor['name']
|
|
60
|
+
else
|
|
61
|
+
# no cursor, then we're ready
|
|
62
|
+
@offset = @total
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Processes the API response body and returns it unchanged.
|
|
67
|
+
# This method can be overridden to handle specific response parsing needs.
|
|
68
|
+
#
|
|
69
|
+
# @param body [Hash, Array, String] The response body from the API
|
|
70
|
+
# @return [Hash, Array, String] Processed data (unchanged)
|
|
71
|
+
def self.data(body)
|
|
72
|
+
return body if body.is_a?(Array)
|
|
73
|
+
body['results'] || body
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Checks if more pages are available.
|
|
77
|
+
# More pages are available if the data has cursor records or if we just start with getting the first page.
|
|
78
|
+
#
|
|
79
|
+
# @return [Boolean] `true` if more pages are available, `false` otherwise
|
|
80
|
+
def more_pages?
|
|
81
|
+
@offset.zero? || @offset < @total
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
data/lib/ninjaone/version.rb
CHANGED
data/lib/ninjaone.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'wrapi'
|
|
4
4
|
require File.expand_path('ninjaone/api', __dir__)
|
|
5
|
+
require File.expand_path('ninjaone/cursor_pagination', __dir__)
|
|
5
6
|
require File.expand_path('ninjaone/client', __dir__)
|
|
6
7
|
require File.expand_path('ninjaone/version', __dir__)
|
|
7
8
|
|
|
@@ -15,6 +16,7 @@ module NinjaOne
|
|
|
15
16
|
|
|
16
17
|
# Default User-Agent header sent with API requests, including gem version information.
|
|
17
18
|
DEFAULT_UA = "NinjaOne Ruby API wrapper #{NinjaOne::VERSION}"
|
|
19
|
+
DEFAULT_PAGINATION = RequestPagination::CursorPagination
|
|
18
20
|
|
|
19
21
|
# Creates and returns a new NinjaOne API client with the given options.
|
|
20
22
|
#
|
|
@@ -30,7 +32,8 @@ module NinjaOne
|
|
|
30
32
|
# client = NinjaOne.client(endpoint: "https://api.custom-endpoint.com", user_agent: "Custom UA/1.0")
|
|
31
33
|
def self.client(options = {})
|
|
32
34
|
NinjaOne::Client.new({
|
|
33
|
-
user_agent: DEFAULT_UA
|
|
35
|
+
user_agent: DEFAULT_UA,
|
|
36
|
+
pagination_class: DEFAULT_PAGINATION
|
|
34
37
|
}.merge(options))
|
|
35
38
|
end
|
|
36
39
|
|
|
@@ -46,5 +49,6 @@ module NinjaOne
|
|
|
46
49
|
def self.reset
|
|
47
50
|
super
|
|
48
51
|
self.user_agent = DEFAULT_UA
|
|
52
|
+
self.pagination_class = DEFAULT_PAGINATION
|
|
49
53
|
end
|
|
50
54
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ninjaone
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Janco Tanis
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-01-
|
|
10
|
+
date: 2026-01-19 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: faraday
|
|
@@ -111,7 +111,10 @@ files:
|
|
|
111
111
|
- lib/ninjaone/client/backup.rb
|
|
112
112
|
- lib/ninjaone/client/devices.rb
|
|
113
113
|
- lib/ninjaone/client/organizations.rb
|
|
114
|
+
- lib/ninjaone/client/queries.rb
|
|
114
115
|
- lib/ninjaone/client/system.rb
|
|
116
|
+
- lib/ninjaone/client/users.rb
|
|
117
|
+
- lib/ninjaone/cursor_pagination.rb
|
|
115
118
|
- lib/ninjaone/error.rb
|
|
116
119
|
- lib/ninjaone/version.rb
|
|
117
120
|
- ninjaone.gemspec
|