lex-service_now 0.1.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/.rubocop.yml +1 -1
- data/CHANGELOG.md +45 -0
- data/CLAUDE.md +160 -0
- data/README.md +199 -0
- data/lex-service_now.gemspec +1 -0
- data/lib/legion/extensions/service_now/access_control/runners/access_control.rb +54 -0
- data/lib/legion/extensions/service_now/aggregate/runners/aggregate.rb +35 -0
- data/lib/legion/extensions/service_now/approval/runners/approval.rb +50 -0
- data/lib/legion/extensions/service_now/asset/runners/asset.rb +65 -0
- data/lib/legion/extensions/service_now/attachment/runners/attachment.rb +74 -0
- data/lib/legion/extensions/service_now/audit/runners/audit.rb +45 -0
- data/lib/legion/extensions/service_now/business_rule/runners/business_rule.rb +63 -0
- data/lib/legion/extensions/service_now/calendar/runners/calendar.rb +60 -0
- data/lib/legion/extensions/service_now/catalog_task/runners/catalog_task.rb +51 -0
- data/lib/legion/extensions/service_now/catalog_variable/runners/catalog_variable.rb +60 -0
- data/lib/legion/extensions/service_now/change/runners/change.rb +4 -4
- data/lib/legion/extensions/service_now/ci_relationship/runners/ci_relationship.rb +52 -0
- data/lib/legion/extensions/service_now/client.rb +58 -0
- data/lib/legion/extensions/service_now/cmdb_health/runners/cmdb_health.rb +48 -0
- data/lib/legion/extensions/service_now/company/runners/company.rb +55 -0
- data/lib/legion/extensions/service_now/contract/runners/contract.rb +55 -0
- data/lib/legion/extensions/service_now/cost_center/runners/cost_center.rb +52 -0
- data/lib/legion/extensions/service_now/currency/runners/currency.rb +40 -0
- data/lib/legion/extensions/service_now/department/runners/department.rb +56 -0
- data/lib/legion/extensions/service_now/deprecation_log/runners/deprecation_log.rb +43 -0
- data/lib/legion/extensions/service_now/discovery/runners/discovery.rb +53 -0
- data/lib/legion/extensions/service_now/email_log/runners/email_log.rb +38 -0
- data/lib/legion/extensions/service_now/errors.rb +26 -0
- data/lib/legion/extensions/service_now/event/runners/event.rb +40 -0
- data/lib/legion/extensions/service_now/flow/runners/flow.rb +52 -0
- data/lib/legion/extensions/service_now/helpers/client.rb +32 -0
- data/lib/legion/extensions/service_now/helpers/pagination.rb +31 -0
- data/lib/legion/extensions/service_now/helpers/retry.rb +32 -0
- data/lib/legion/extensions/service_now/hr_case/runners/hr_case.rb +55 -0
- data/lib/legion/extensions/service_now/import_set/runners/import_set.rb +31 -0
- data/lib/legion/extensions/service_now/incident/runners/incident.rb +77 -0
- data/lib/legion/extensions/service_now/knowledge_base/runners/knowledge_base.rb +64 -0
- data/lib/legion/extensions/service_now/knowledge_feedback/runners/knowledge_feedback.rb +45 -0
- data/lib/legion/extensions/service_now/license/runners/license.rb +44 -0
- data/lib/legion/extensions/service_now/location/runners/location.rb +59 -0
- data/lib/legion/extensions/service_now/metric/runners/metric.rb +47 -0
- data/lib/legion/extensions/service_now/mid_server/runners/mid_server.rb +54 -0
- data/lib/legion/extensions/service_now/notification/runners/notification.rb +56 -0
- data/lib/legion/extensions/service_now/on_call/runners/on_call.rb +52 -0
- data/lib/legion/extensions/service_now/performance_analytics/runners/performance_analytics.rb +51 -0
- data/lib/legion/extensions/service_now/problem/runners/problem.rb +73 -0
- data/lib/legion/extensions/service_now/project/runners/project.rb +67 -0
- data/lib/legion/extensions/service_now/release/runners/release.rb +54 -0
- data/lib/legion/extensions/service_now/request/runners/request.rb +62 -0
- data/lib/legion/extensions/service_now/scheduled_job/runners/scheduled_job.rb +54 -0
- data/lib/legion/extensions/service_now/script_action/runners/script_action.rb +50 -0
- data/lib/legion/extensions/service_now/script_include/runners/script_include.rb +55 -0
- data/lib/legion/extensions/service_now/security_incident/runners/security_incident.rb +58 -0
- data/lib/legion/extensions/service_now/skills/approval_workflow.rb +51 -0
- data/lib/legion/extensions/service_now/skills/asset_management.rb +52 -0
- data/lib/legion/extensions/service_now/skills/problem_management.rb +60 -0
- data/lib/legion/extensions/service_now/skills/request_fulfillment.rb +60 -0
- data/lib/legion/extensions/service_now/skills/security_incident_response.rb +60 -0
- data/lib/legion/extensions/service_now/sla/runners/sla.rb +49 -0
- data/lib/legion/extensions/service_now/survey/runners/survey.rb +52 -0
- data/lib/legion/extensions/service_now/system_property/runners/system_property.rb +54 -0
- data/lib/legion/extensions/service_now/table/runners/table.rb +56 -0
- data/lib/legion/extensions/service_now/tag/runners/tag.rb +61 -0
- data/lib/legion/extensions/service_now/task/runners/task.rb +56 -0
- data/lib/legion/extensions/service_now/ui_action/runners/ui_action.rb +53 -0
- data/lib/legion/extensions/service_now/ui_policy/runners/ui_policy.rb +51 -0
- data/lib/legion/extensions/service_now/update_set/runners/update_set.rb +61 -0
- data/lib/legion/extensions/service_now/user/runners/user.rb +74 -0
- data/lib/legion/extensions/service_now/user_group/runners/user_group.rb +79 -0
- data/lib/legion/extensions/service_now/vendor/runners/vendor.rb +61 -0
- data/lib/legion/extensions/service_now/version.rb +1 -1
- data/lib/legion/extensions/service_now/work_order/runners/work_order.rb +66 -0
- data/lib/legion/extensions/service_now/workflow/runners/workflow.rb +59 -0
- data/lib/legion/extensions/service_now.rb +64 -0
- metadata +81 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7299f2cb64f753600e58b75350804a51164e4ed0b246a0124e9dd691ae813860
|
|
4
|
+
data.tar.gz: 4cdb63326d0a106814c0f6abb67bf819198e0114d299dbf971a3185ed3b75f8c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 619c90c1289c5b046076a55290a5969d51605b5491ad3163a4038de98d99e06294b62774d5a3d24592ec27f0705ab759df3aafca91778be7c6af10f8d0e0d3ea
|
|
7
|
+
data.tar.gz: 3ee2c4fb6921cf67f71139d9a288d6d056302a0b403f63dcb6b809dfb3667ca00b7689255e5ade8bb188d618a97169338b71673b7c8febb99401ca7e2e493374
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.0] - 2026-04-22
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Incident runner (6 methods)
|
|
7
|
+
- Problem runner (6 methods)
|
|
8
|
+
- Attachment runner (5 methods) with multipart upload support
|
|
9
|
+
- Table runner (5 methods) — generic CRUD escape hatch for any table
|
|
10
|
+
- Aggregate runner (1 method) — stats/count/sum/avg queries
|
|
11
|
+
- User runner (7 methods) including lookup by username and email
|
|
12
|
+
- UserGroup runner (9 methods) including member management
|
|
13
|
+
- Request/RITM runner (6 methods)
|
|
14
|
+
- Approval runner (5 methods) — approve, reject, list_for_record
|
|
15
|
+
- Task runner (5 methods) including add_work_note
|
|
16
|
+
- SLA runner (5 methods) — definitions and task SLA tracking
|
|
17
|
+
- ImportSet runner (2 methods)
|
|
18
|
+
- Event runner (3 methods)
|
|
19
|
+
- PerformanceAnalytics runner (5 methods) — widgets, scorecards, indicators
|
|
20
|
+
- Flow/Subflow runner (6 methods)
|
|
21
|
+
- Notification runner (5 methods)
|
|
22
|
+
- EmailLog runner (3 methods)
|
|
23
|
+
- Audit runner (3 methods) — field change history
|
|
24
|
+
- SystemProperty runner (6 methods)
|
|
25
|
+
- Asset runner (6 methods) including hardware
|
|
26
|
+
- Location runner (5 methods)
|
|
27
|
+
- Department runner (5 methods)
|
|
28
|
+
- Company runner (5 methods)
|
|
29
|
+
- Project runner (6 methods) including project tasks
|
|
30
|
+
- Release runner (5 methods)
|
|
31
|
+
- HrCase runner (5 methods)
|
|
32
|
+
- SecurityIncident runner (5 methods)
|
|
33
|
+
- UpdateSet runner (6 methods) including change listing
|
|
34
|
+
- ScriptInclude runner (5 methods)
|
|
35
|
+
- BusinessRule runner (5 methods)
|
|
36
|
+
- ScheduledJob runner (5 methods)
|
|
37
|
+
- OnCall runner (5 methods) — schedules, members, who_is_on_call
|
|
38
|
+
- Survey runner (5 methods) — instances and responses
|
|
39
|
+
- Contract runner (5 methods)
|
|
40
|
+
- CostCenter runner (5 methods)
|
|
41
|
+
- WorkOrder runner (6 methods) including tasks
|
|
42
|
+
- Discovery runner (5 methods)
|
|
43
|
+
- MidServer runner (5 methods)
|
|
44
|
+
- CatalogVariable runner (5 methods)
|
|
45
|
+
- Workflow runner (6 methods) — contexts and cancellation
|
|
46
|
+
- 10 LLM skills: Incident, ChangeRequest, CmdbQuery, Knowledge, ServiceCatalog, ProblemManagement, RequestFulfillment, ApprovalWorkflow, AssetManagement, SecurityIncidentResponse
|
|
47
|
+
|
|
3
48
|
## [0.1.0] - 2026-04-22
|
|
4
49
|
|
|
5
50
|
### Added
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# lex-service_now: ServiceNow Integration for LegionIO
|
|
2
|
+
|
|
3
|
+
**Repository Level 3 Documentation**
|
|
4
|
+
- **Parent**: `/Users/miverso2/rubymine/legion/extensions-other/CLAUDE.md`
|
|
5
|
+
- **Grandparent**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Comprehensive Legion Extension connecting LegionIO to ServiceNow via REST APIs. Covers 46 domains spanning ITSM, ITOM, ITAM, HR, Security, DevOps, and platform administration.
|
|
10
|
+
|
|
11
|
+
**Version**: 0.2.0
|
|
12
|
+
**GitHub**: https://github.com/LegionIO/lex-service_now
|
|
13
|
+
**License**: MIT
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Legion::Extensions::ServiceNow
|
|
19
|
+
+-- Helpers/
|
|
20
|
+
| +-- Client # connection() with OAuth2→Bearer→Basic auth priority fallback
|
|
21
|
+
+-- ITSM/
|
|
22
|
+
| +-- Change::Runners::Change (14 methods) — normal/emergency/standard + tasks/conflicts/approvals
|
|
23
|
+
| +-- Incident::Runners::Incident (6 methods) — CRUD + resolve
|
|
24
|
+
| +-- Problem::Runners::Problem (6 methods) — CRUD + close
|
|
25
|
+
| +-- Request::Runners::Request (6 methods) — sc_request + sc_req_item
|
|
26
|
+
| +-- Approval::Runners::Approval (5 methods) — approve/reject + list_for_record
|
|
27
|
+
| +-- Task::Runners::Task (5 methods) — CRUD + add_work_note
|
|
28
|
+
| +-- Sla::Runners::Sla (5 methods) — definitions + task SLAs
|
|
29
|
+
+-- CMDB/
|
|
30
|
+
| +-- Cmdb::Instance::Runners::Instance (7 methods) — CI CRUD + relationships
|
|
31
|
+
| +-- Cmdb::Meta::Runners::Meta (2 methods) — hierarchy + class metadata
|
|
32
|
+
+-- Knowledge/
|
|
33
|
+
| +-- Knowledge::Runners::Knowledge (5 methods) — article CRUD
|
|
34
|
+
+-- ServiceCatalog/
|
|
35
|
+
| +-- ServiceCatalog::Runners::ServiceCatalog (11 methods) — catalogs/items/cart/order
|
|
36
|
+
| +-- CatalogVariable::Runners::CatalogVariable (5 methods) — item variables CRUD
|
|
37
|
+
+-- User Management/
|
|
38
|
+
| +-- User::Runners::User (7 methods) — CRUD + lookup_by_username/email
|
|
39
|
+
| +-- UserGroup::Runners::UserGroup (9 methods) — CRUD + member management
|
|
40
|
+
| +-- Account::Runners::Account (4 methods) — core account CRUD
|
|
41
|
+
+-- Assets/
|
|
42
|
+
| +-- Asset::Runners::Asset (6 methods) — alm_asset CRUD + hardware
|
|
43
|
+
| +-- Contract::Runners::Contract (5 methods) — ast_contract CRUD
|
|
44
|
+
+-- Organization/
|
|
45
|
+
| +-- Location::Runners::Location (5 methods) — cmn_location CRUD
|
|
46
|
+
| +-- Department::Runners::Department (5 methods) — cmn_department CRUD
|
|
47
|
+
| +-- Company::Runners::Company (5 methods) — core_company CRUD
|
|
48
|
+
| +-- CostCenter::Runners::CostCenter (5 methods) — cmn_cost_center CRUD
|
|
49
|
+
+-- Project & Release/
|
|
50
|
+
| +-- Project::Runners::Project (6 methods) — pm_project CRUD + tasks
|
|
51
|
+
| +-- Release::Runners::Release (5 methods) — rm_release CRUD
|
|
52
|
+
+-- Security/
|
|
53
|
+
| +-- SecurityIncident::Runners::SecurityIncident (5 methods) — sn_si_incident CRUD
|
|
54
|
+
+-- HR/
|
|
55
|
+
| +-- HrCase::Runners::HrCase (5 methods) — sn_hr_core_case CRUD
|
|
56
|
+
+-- Platform Admin/
|
|
57
|
+
| +-- SystemProperty::Runners::SystemProperty (6 methods) — sys_properties CRUD
|
|
58
|
+
| +-- UpdateSet::Runners::UpdateSet (6 methods) — CRUD + list changes
|
|
59
|
+
| +-- ScriptInclude::Runners::ScriptInclude (5 methods) — sys_script_include CRUD
|
|
60
|
+
| +-- BusinessRule::Runners::BusinessRule (5 methods) — sys_script CRUD
|
|
61
|
+
| +-- ScheduledJob::Runners::ScheduledJob (5 methods) — sysauto_script CRUD
|
|
62
|
+
| +-- Workflow::Runners::Workflow (6 methods) — wf_workflow + contexts
|
|
63
|
+
| +-- Flow::Runners::Flow (6 methods) — sn_fd flow execute + subflows
|
|
64
|
+
| +-- Audit::Runners::Audit (3 methods) — sys_audit + field changes
|
|
65
|
+
+-- ITOM/
|
|
66
|
+
| +-- Discovery::Runners::Discovery (5 methods) — schedules/logs/devices
|
|
67
|
+
| +-- MidServer::Runners::MidServer (5 methods) — ecc_agent CRUD + capabilities
|
|
68
|
+
| +-- Event::Runners::Event (3 methods) — sysevent CRUD
|
|
69
|
+
+-- Analytics/
|
|
70
|
+
| +-- PerformanceAnalytics::Runners::PerformanceAnalytics (5 methods) — widgets/scorecards/indicators
|
|
71
|
+
| +-- Aggregate::Runners::Aggregate (1 method) — stats queries on any table
|
|
72
|
+
+-- Comms/
|
|
73
|
+
| +-- Notification::Runners::Notification (5 methods) — sysevent_email_action CRUD
|
|
74
|
+
| +-- EmailLog::Runners::EmailLog (3 methods) — sys_email list/get/list_for_record
|
|
75
|
+
+-- Field Service/
|
|
76
|
+
| +-- WorkOrder::Runners::WorkOrder (6 methods) — wm_order CRUD + tasks + close
|
|
77
|
+
| +-- OnCall::Runners::OnCall (5 methods) — cmn_rota + members + who_is_on_call
|
|
78
|
+
+-- Utilities/
|
|
79
|
+
| +-- Table::Runners::Table (5 methods) — generic CRUD on any table
|
|
80
|
+
| +-- ImportSet::Runners::ImportSet (2 methods) — /api/now/import
|
|
81
|
+
| +-- Survey::Runners::Survey (5 methods) — assessments + instances + responses
|
|
82
|
+
+-- Skills/ (loaded only if legion-llm available)
|
|
83
|
+
| +-- Incident, ChangeRequest, CmdbQuery, Knowledge, ServiceCatalog
|
|
84
|
+
| +-- ProblemManagement, RequestFulfillment, ApprovalWorkflow
|
|
85
|
+
| +-- AssetManagement, SecurityIncidentResponse
|
|
86
|
+
+-- Client # Standalone client class including all 46 runners
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Authentication
|
|
90
|
+
|
|
91
|
+
`Helpers::Client#connection` selects auth priority order (most secure first):
|
|
92
|
+
1. **OAuth2** — `client_id` + `client_secret` → client credentials grant → `/oauth_token.do`, token memoized in `@fetch_oauth2_token`
|
|
93
|
+
2. **Bearer** — `token` → `Authorization: Bearer <token>`
|
|
94
|
+
3. **Basic Auth** — `username` + `password` → HTTP Basic
|
|
95
|
+
|
|
96
|
+
Instance URL defaults to `Legion::Settings[:service_now][:url]`, overridable per `Client.new` or per call.
|
|
97
|
+
|
|
98
|
+
## Standalone Client
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
client = Legion::Extensions::ServiceNow::Client.new(
|
|
102
|
+
url: 'https://your-instance.service-now.com',
|
|
103
|
+
username: 'svc_account',
|
|
104
|
+
password: 'secret'
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# Or with OAuth2
|
|
108
|
+
client = Legion::Extensions::ServiceNow::Client.new(
|
|
109
|
+
url: 'https://your-instance.service-now.com',
|
|
110
|
+
client_id: 'abc',
|
|
111
|
+
client_secret: 'xyz'
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
client.list_incidents(sysparm_query: 'state=1', sysparm_limit: 50)
|
|
115
|
+
client.create_change(short_description: 'Deploy v2.0')
|
|
116
|
+
client.get_ci(class_name: 'cmdb_ci_server', sys_id: 'abc123')
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Settings
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"service_now": {
|
|
124
|
+
"url": "https://your-instance.service-now.com",
|
|
125
|
+
"username": null,
|
|
126
|
+
"password": null,
|
|
127
|
+
"token": null,
|
|
128
|
+
"client_id": null,
|
|
129
|
+
"client_secret": null
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Dependencies
|
|
135
|
+
|
|
136
|
+
| Gem | Purpose |
|
|
137
|
+
|-----|---------|
|
|
138
|
+
| `faraday >= 2.0` | HTTP client |
|
|
139
|
+
| `faraday-multipart >= 1.0` | Multipart upload for attachments |
|
|
140
|
+
| `legion-settings >= 1.3.14` | Settings/config |
|
|
141
|
+
| `legion-logging >= 1.3.2` | Structured logging |
|
|
142
|
+
| `legion-cache >= 1.3.11` | Caching |
|
|
143
|
+
| `legion-crypt >= 1.4.9` | Credential encryption |
|
|
144
|
+
| `legion-data >= 1.4.17` | ORM |
|
|
145
|
+
| `legion-json >= 1.2.1` | JSON helpers |
|
|
146
|
+
| `legion-transport >= 1.3.9` | AMQP transport |
|
|
147
|
+
|
|
148
|
+
`legion-llm` is an optional soft dependency — skills load only if defined.
|
|
149
|
+
|
|
150
|
+
## Development
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
bundle install
|
|
154
|
+
bundle exec rspec # 217+ examples, 0 failures
|
|
155
|
+
bundle exec rubocop # 0 offenses
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
**Maintained By**: Matthew Iverson (@Esity)
|
data/README.md
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# lex-service_now
|
|
2
|
+
|
|
3
|
+
A LegionIO extension connecting Legion to ServiceNow via REST APIs. Covers 46 domains spanning ITSM, ITOM, ITAM, HR, Security, DevOps, and platform administration.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add to your Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'lex-service_now'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
Set credentials via Legion settings (`~/.legionio/settings/service_now.json`):
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"service_now": {
|
|
20
|
+
"url": "https://your-instance.service-now.com",
|
|
21
|
+
"username": "svc_account",
|
|
22
|
+
"password": "secret"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
OAuth2 and Bearer token auth are also supported — the most secure credentials provided are used automatically (OAuth2 > Bearer > Basic Auth).
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Standalone Client
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
require 'legion/extensions/service_now'
|
|
35
|
+
|
|
36
|
+
client = Legion::Extensions::ServiceNow::Client.new(
|
|
37
|
+
url: 'https://your-instance.service-now.com',
|
|
38
|
+
username: 'admin',
|
|
39
|
+
password: 'secret'
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Incidents
|
|
43
|
+
client.list_incidents(sysparm_query: 'state=1^priority=1', sysparm_limit: 10)
|
|
44
|
+
client.create_incident(short_description: 'Production server down', urgency: '1', impact: '1')
|
|
45
|
+
client.resolve_incident(sys_id: 'abc123', close_code: 'Solved (Permanently)', close_notes: 'Fixed')
|
|
46
|
+
|
|
47
|
+
# Change Management
|
|
48
|
+
client.create_normal(short_description: 'Deploy app v2.0', assignment_group: 'CAB Approval')
|
|
49
|
+
client.get_change(id: 'CHG0012345')
|
|
50
|
+
client.get_approvals(id: 'CHG0012345')
|
|
51
|
+
|
|
52
|
+
# CMDB
|
|
53
|
+
client.list_cis(class_name: 'cmdb_ci_server', sysparm_query: 'operational_status=1')
|
|
54
|
+
client.get_relationships(class_name: 'cmdb_ci_server', sys_id: 'srv001')
|
|
55
|
+
|
|
56
|
+
# Service Catalog
|
|
57
|
+
client.list_items(catalog_id: 'cat1')
|
|
58
|
+
client.order_now(sys_id: 'item_id', quantity: 1, variables: { justification: 'Project work' })
|
|
59
|
+
|
|
60
|
+
# Users & Groups
|
|
61
|
+
client.get_user_by_email(email: 'jdoe@company.com')
|
|
62
|
+
client.list_group_members(group_sys_id: 'network_team_id')
|
|
63
|
+
|
|
64
|
+
# Generic Table API (escape hatch for any table)
|
|
65
|
+
client.table_list(table_name: 'u_custom_table', sysparm_query: 'active=true')
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Supported Domains
|
|
69
|
+
|
|
70
|
+
### ITSM
|
|
71
|
+
| Domain | Methods | Table |
|
|
72
|
+
|--------|---------|-------|
|
|
73
|
+
| Change | 14 | `sn_chg_rest` API |
|
|
74
|
+
| Incident | 6 | `incident` |
|
|
75
|
+
| Problem | 6 | `problem` |
|
|
76
|
+
| Request/RITM | 6 | `sc_request`, `sc_req_item` |
|
|
77
|
+
| Approval | 5 | `sysapproval_approver` |
|
|
78
|
+
| Task | 5 | `task` |
|
|
79
|
+
| SLA | 5 | `contract_sla`, `task_sla` |
|
|
80
|
+
|
|
81
|
+
### CMDB & Discovery
|
|
82
|
+
| Domain | Methods | Table |
|
|
83
|
+
|--------|---------|-------|
|
|
84
|
+
| CMDB Instance | 7 | `/api/now/cmdb/instance` |
|
|
85
|
+
| CMDB Meta | 2 | `/api/now/doc/meta` |
|
|
86
|
+
| Discovery | 5 | `discovery_schedule`, `discovery_log` |
|
|
87
|
+
| MID Server | 5 | `ecc_agent` |
|
|
88
|
+
|
|
89
|
+
### Service Catalog
|
|
90
|
+
| Domain | Methods | Table |
|
|
91
|
+
|--------|---------|-------|
|
|
92
|
+
| Service Catalog | 11 | `/api/sn_sc/servicecatalog` |
|
|
93
|
+
| Catalog Variable | 5 | `item_option_new` |
|
|
94
|
+
|
|
95
|
+
### Knowledge & Content
|
|
96
|
+
| Domain | Methods | Table |
|
|
97
|
+
|--------|---------|-------|
|
|
98
|
+
| Knowledge | 5 | `/api/sn_km_api/knowledge` |
|
|
99
|
+
| Survey | 5 | `survey`, `asmt_assessment_instance` |
|
|
100
|
+
|
|
101
|
+
### User & Organization
|
|
102
|
+
| Domain | Methods | Table |
|
|
103
|
+
|--------|---------|-------|
|
|
104
|
+
| User | 7 | `sys_user` |
|
|
105
|
+
| UserGroup | 9 | `sys_user_group`, `sys_user_grmember` |
|
|
106
|
+
| Account | 4 | `account` |
|
|
107
|
+
| Location | 5 | `cmn_location` |
|
|
108
|
+
| Department | 5 | `cmn_department` |
|
|
109
|
+
| Company | 5 | `core_company` |
|
|
110
|
+
| Cost Center | 5 | `cmn_cost_center` |
|
|
111
|
+
|
|
112
|
+
### Asset & Contract Management
|
|
113
|
+
| Domain | Methods | Table |
|
|
114
|
+
|--------|---------|-------|
|
|
115
|
+
| Asset | 6 | `alm_asset`, `alm_hardware` |
|
|
116
|
+
| Contract | 5 | `ast_contract` |
|
|
117
|
+
|
|
118
|
+
### Security
|
|
119
|
+
| Domain | Methods | Table |
|
|
120
|
+
|--------|---------|-------|
|
|
121
|
+
| Security Incident | 5 | `sn_si_incident` |
|
|
122
|
+
|
|
123
|
+
### HR
|
|
124
|
+
| Domain | Methods | Table |
|
|
125
|
+
|--------|---------|-------|
|
|
126
|
+
| HR Case | 5 | `sn_hr_core_case` |
|
|
127
|
+
|
|
128
|
+
### Project & Release
|
|
129
|
+
| Domain | Methods | Table |
|
|
130
|
+
|--------|---------|-------|
|
|
131
|
+
| Project | 6 | `pm_project`, `pm_project_task` |
|
|
132
|
+
| Release | 5 | `rm_release` |
|
|
133
|
+
|
|
134
|
+
### Platform Administration
|
|
135
|
+
| Domain | Methods | Table |
|
|
136
|
+
|--------|---------|-------|
|
|
137
|
+
| System Property | 6 | `sys_properties` |
|
|
138
|
+
| Update Set | 6 | `sys_update_set`, `sys_update_xml` |
|
|
139
|
+
| Script Include | 5 | `sys_script_include` |
|
|
140
|
+
| Business Rule | 5 | `sys_script` |
|
|
141
|
+
| Scheduled Job | 5 | `sysauto_script` |
|
|
142
|
+
| Workflow | 6 | `wf_workflow`, `wf_context` |
|
|
143
|
+
| Flow/Subflow | 6 | `/api/sn_fd` |
|
|
144
|
+
| Audit | 3 | `sys_audit` |
|
|
145
|
+
|
|
146
|
+
### ITOM & Monitoring
|
|
147
|
+
| Domain | Methods | Table |
|
|
148
|
+
|--------|---------|-------|
|
|
149
|
+
| Event | 3 | `sysevent` |
|
|
150
|
+
| Performance Analytics | 5 | `/api/now/pa` |
|
|
151
|
+
|
|
152
|
+
### Communications
|
|
153
|
+
| Domain | Methods | Table |
|
|
154
|
+
|--------|---------|-------|
|
|
155
|
+
| Notification | 5 | `sysevent_email_action` |
|
|
156
|
+
| Email Log | 3 | `sys_email` |
|
|
157
|
+
|
|
158
|
+
### Field Service
|
|
159
|
+
| Domain | Methods | Table |
|
|
160
|
+
|--------|---------|-------|
|
|
161
|
+
| Work Order | 6 | `wm_order`, `wm_task` |
|
|
162
|
+
| On-Call | 5 | `cmn_rota`, `cmn_rota_member` |
|
|
163
|
+
|
|
164
|
+
### Utilities
|
|
165
|
+
| Domain | Methods | Table |
|
|
166
|
+
|--------|---------|-------|
|
|
167
|
+
| Table (generic) | 5 | Any table via `/api/now/table/{table}` |
|
|
168
|
+
| Import Set | 2 | `/api/now/import` |
|
|
169
|
+
| Aggregate | 1 | `/api/now/stats/{table}` |
|
|
170
|
+
| Attachment | 5 | `/api/now/attachment` |
|
|
171
|
+
|
|
172
|
+
## LLM Skills
|
|
173
|
+
|
|
174
|
+
When `legion-llm` is available, 10 workflow skills are registered automatically:
|
|
175
|
+
|
|
176
|
+
| Skill | Trigger Words |
|
|
177
|
+
|-------|--------------|
|
|
178
|
+
| `servicenow:incident` | incident, INC, outage, p1, sev1 |
|
|
179
|
+
| `servicenow:change_request` | CHG, RFC, change request, CAB |
|
|
180
|
+
| `servicenow:cmdb_query` | CMDB, CI, configuration item |
|
|
181
|
+
| `servicenow:knowledge` | KB, knowledge base, article |
|
|
182
|
+
| `servicenow:service_catalog` | catalog, service request, order |
|
|
183
|
+
| `servicenow:problem_management` | PRB, problem, root cause, RCA |
|
|
184
|
+
| `servicenow:request_fulfillment` | RITM, request item, fulfillment |
|
|
185
|
+
| `servicenow:approval_workflow` | approval, approve, reject |
|
|
186
|
+
| `servicenow:asset_management` | asset, hardware, inventory, ALM |
|
|
187
|
+
| `servicenow:security_incident_response` | SIR, security incident, breach |
|
|
188
|
+
|
|
189
|
+
## Development
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
bundle install
|
|
193
|
+
bundle exec rspec # 217 examples, 0 failures
|
|
194
|
+
bundle exec rubocop # 0 offenses
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
MIT — see [LICENSE](LICENSE).
|
data/lex-service_now.gemspec
CHANGED
|
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
spec.require_paths = ['lib']
|
|
26
26
|
|
|
27
27
|
spec.add_dependency 'faraday', '>= 2.0'
|
|
28
|
+
spec.add_dependency 'faraday-multipart', '>= 1.0'
|
|
28
29
|
spec.add_dependency 'legion-cache', '>= 1.3.11'
|
|
29
30
|
spec.add_dependency 'legion-crypt', '>= 1.4.9'
|
|
30
31
|
spec.add_dependency 'legion-data', '>= 1.4.17'
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module ServiceNow
|
|
6
|
+
module AccessControl
|
|
7
|
+
module Runners
|
|
8
|
+
module AccessControl
|
|
9
|
+
include Legion::Extensions::ServiceNow::Helpers::Client
|
|
10
|
+
|
|
11
|
+
def list_acls(sysparm_limit: 100, sysparm_offset: 0,
|
|
12
|
+
sysparm_query: nil, **)
|
|
13
|
+
params = { sysparm_limit: sysparm_limit, sysparm_offset: sysparm_offset }
|
|
14
|
+
params[:sysparm_query] = sysparm_query if sysparm_query
|
|
15
|
+
resp = connection(**).get('/api/now/table/sys_security_acl', params)
|
|
16
|
+
{ acls: resp.body['result'] }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def get_acl(sys_id:, **)
|
|
20
|
+
resp = connection(**).get("/api/now/table/sys_security_acl/#{sys_id}")
|
|
21
|
+
{ acl: resp.body['result'] }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def create_acl(name:, type:, operation:, active: true,
|
|
25
|
+
script: nil, condition: nil, **)
|
|
26
|
+
body = { name: name, type: type, operation: operation, active: active }
|
|
27
|
+
body[:script] = script if script
|
|
28
|
+
body[:condition] = condition if condition
|
|
29
|
+
resp = connection(**).post('/api/now/table/sys_security_acl', body)
|
|
30
|
+
{ acl: resp.body['result'] }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def update_acl(sys_id:, active: nil, script: nil, condition: nil, **)
|
|
34
|
+
body = {}
|
|
35
|
+
body[:active] = active unless active.nil?
|
|
36
|
+
body[:script] = script if script
|
|
37
|
+
body[:condition] = condition if condition
|
|
38
|
+
resp = connection(**).patch("/api/now/table/sys_security_acl/#{sys_id}", body)
|
|
39
|
+
{ acl: resp.body['result'] }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def delete_acl(sys_id:, **)
|
|
43
|
+
resp = connection(**).delete("/api/now/table/sys_security_acl/#{sys_id}")
|
|
44
|
+
{ deleted: resp.status == 204, sys_id: sys_id }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
|
|
48
|
+
Legion::Extensions::Helpers.const_defined?(:Lex, false)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module ServiceNow
|
|
6
|
+
module Aggregate
|
|
7
|
+
module Runners
|
|
8
|
+
module Aggregate
|
|
9
|
+
include Legion::Extensions::ServiceNow::Helpers::Client
|
|
10
|
+
|
|
11
|
+
def aggregate(table_name:, sysparm_count: nil, sysparm_sum_fields: nil,
|
|
12
|
+
sysparm_avg_fields: nil, sysparm_min_fields: nil,
|
|
13
|
+
sysparm_max_fields: nil, sysparm_query: nil,
|
|
14
|
+
sysparm_group_by: nil, sysparm_having: nil, **)
|
|
15
|
+
params = {}
|
|
16
|
+
params[:sysparm_count] = sysparm_count unless sysparm_count.nil?
|
|
17
|
+
params[:sysparm_sum_fields] = sysparm_sum_fields if sysparm_sum_fields
|
|
18
|
+
params[:sysparm_avg_fields] = sysparm_avg_fields if sysparm_avg_fields
|
|
19
|
+
params[:sysparm_min_fields] = sysparm_min_fields if sysparm_min_fields
|
|
20
|
+
params[:sysparm_max_fields] = sysparm_max_fields if sysparm_max_fields
|
|
21
|
+
params[:sysparm_query] = sysparm_query if sysparm_query
|
|
22
|
+
params[:sysparm_group_by] = sysparm_group_by if sysparm_group_by
|
|
23
|
+
params[:sysparm_having] = sysparm_having if sysparm_having
|
|
24
|
+
resp = connection(**).get("/api/now/stats/#{table_name}", params)
|
|
25
|
+
{ stats: resp.body['result'] }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
|
|
29
|
+
Legion::Extensions::Helpers.const_defined?(:Lex, false)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module ServiceNow
|
|
6
|
+
module Approval
|
|
7
|
+
module Runners
|
|
8
|
+
module Approval
|
|
9
|
+
include Legion::Extensions::ServiceNow::Helpers::Client
|
|
10
|
+
|
|
11
|
+
def list_approvals(sysparm_limit: 100, sysparm_offset: 0, sysparm_query: nil, **)
|
|
12
|
+
params = { sysparm_limit: sysparm_limit, sysparm_offset: sysparm_offset }
|
|
13
|
+
params[:sysparm_query] = sysparm_query if sysparm_query
|
|
14
|
+
resp = connection(**).get('/api/now/table/sysapproval_approver', params)
|
|
15
|
+
{ approvals: resp.body['result'] }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get_approval(sys_id:, **)
|
|
19
|
+
resp = connection(**).get("/api/now/table/sysapproval_approver/#{sys_id}")
|
|
20
|
+
{ approval: resp.body['result'] }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def approve(sys_id:, comments: nil, **)
|
|
24
|
+
body = { state: 'approved' }
|
|
25
|
+
body[:comments] = comments if comments
|
|
26
|
+
resp = connection(**).patch("/api/now/table/sysapproval_approver/#{sys_id}", body)
|
|
27
|
+
{ approval: resp.body['result'] }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def reject(sys_id:, comments: nil, **)
|
|
31
|
+
body = { state: 'rejected' }
|
|
32
|
+
body[:comments] = comments if comments
|
|
33
|
+
resp = connection(**).patch("/api/now/table/sysapproval_approver/#{sys_id}", body)
|
|
34
|
+
{ approval: resp.body['result'] }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def list_approvals_for_record(document_id:, **)
|
|
38
|
+
params = { sysparm_query: "document_id=#{document_id}", sysparm_limit: 100 }
|
|
39
|
+
resp = connection(**).get('/api/now/table/sysapproval_approver', params)
|
|
40
|
+
{ approvals: resp.body['result'] }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
|
|
44
|
+
Legion::Extensions::Helpers.const_defined?(:Lex, false)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module ServiceNow
|
|
6
|
+
module Asset
|
|
7
|
+
module Runners
|
|
8
|
+
module Asset
|
|
9
|
+
include Legion::Extensions::ServiceNow::Helpers::Client
|
|
10
|
+
|
|
11
|
+
def list_assets(sysparm_limit: 100, sysparm_offset: 0, sysparm_query: nil,
|
|
12
|
+
sysparm_fields: nil, **)
|
|
13
|
+
params = { sysparm_limit: sysparm_limit, sysparm_offset: sysparm_offset }
|
|
14
|
+
params[:sysparm_query] = sysparm_query if sysparm_query
|
|
15
|
+
params[:sysparm_fields] = sysparm_fields if sysparm_fields
|
|
16
|
+
resp = connection(**).get('/api/now/table/alm_asset', params)
|
|
17
|
+
{ assets: resp.body['result'] }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def get_asset(sys_id:, **)
|
|
21
|
+
resp = connection(**).get("/api/now/table/alm_asset/#{sys_id}")
|
|
22
|
+
{ asset: resp.body['result'] }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def create_asset(model:, model_category:, serial_number: nil,
|
|
26
|
+
assigned_to: nil, state: nil, **)
|
|
27
|
+
body = { model: model, model_category: model_category }
|
|
28
|
+
body[:serial_number] = serial_number if serial_number
|
|
29
|
+
body[:assigned_to] = assigned_to if assigned_to
|
|
30
|
+
body[:state] = state if state
|
|
31
|
+
resp = connection(**).post('/api/now/table/alm_asset', body)
|
|
32
|
+
{ asset: resp.body['result'] }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def update_asset(sys_id:, state: nil, assigned_to: nil,
|
|
36
|
+
location: nil, serial_number: nil, **)
|
|
37
|
+
body = {}
|
|
38
|
+
body[:state] = state if state
|
|
39
|
+
body[:assigned_to] = assigned_to if assigned_to
|
|
40
|
+
body[:location] = location if location
|
|
41
|
+
body[:serial_number] = serial_number if serial_number
|
|
42
|
+
resp = connection(**).patch("/api/now/table/alm_asset/#{sys_id}", body)
|
|
43
|
+
{ asset: resp.body['result'] }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def delete_asset(sys_id:, **)
|
|
47
|
+
resp = connection(**).delete("/api/now/table/alm_asset/#{sys_id}")
|
|
48
|
+
{ deleted: resp.status == 204, sys_id: sys_id }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def list_hardware(sysparm_limit: 100, sysparm_offset: 0, sysparm_query: nil, **)
|
|
52
|
+
params = { sysparm_limit: sysparm_limit, sysparm_offset: sysparm_offset }
|
|
53
|
+
params[:sysparm_query] = sysparm_query if sysparm_query
|
|
54
|
+
resp = connection(**).get('/api/now/table/alm_hardware', params)
|
|
55
|
+
{ hardware: resp.body['result'] }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
|
|
59
|
+
Legion::Extensions::Helpers.const_defined?(:Lex, false)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|