lex-nautobot 0.1.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 +7 -0
- data/.github/CODEOWNERS +7 -0
- data/.github/dependabot.yml +18 -0
- data/.github/workflows/ci.yml +34 -0
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/.rspec_status +83 -0
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +18 -0
- data/CLAUDE.md +33 -0
- data/Gemfile +13 -0
- data/LICENSE +21 -0
- data/README.md +78 -0
- data/lex-nautobot.gemspec +37 -0
- data/lib/legion/extensions/nautobot/client.rb +43 -0
- data/lib/legion/extensions/nautobot/errors.rb +9 -0
- data/lib/legion/extensions/nautobot/helpers/client.rb +23 -0
- data/lib/legion/extensions/nautobot/runners/circuits.rb +127 -0
- data/lib/legion/extensions/nautobot/runners/cloud.rb +109 -0
- data/lib/legion/extensions/nautobot/runners/dcim.rb +351 -0
- data/lib/legion/extensions/nautobot/runners/extras.rb +311 -0
- data/lib/legion/extensions/nautobot/runners/ipam.rb +210 -0
- data/lib/legion/extensions/nautobot/runners/tenancy.rb +80 -0
- data/lib/legion/extensions/nautobot/runners/users.rb +60 -0
- data/lib/legion/extensions/nautobot/runners/virtualization.rb +147 -0
- data/lib/legion/extensions/nautobot/runners/vpn.rb +120 -0
- data/lib/legion/extensions/nautobot/runners/wireless.rb +57 -0
- data/lib/legion/extensions/nautobot/version.rb +9 -0
- data/lib/legion/extensions/nautobot.rb +24 -0
- metadata +187 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: bfa4f3436a116f0bf036325951165dfe98ef17c2107d047a144c954d6c303735
|
|
4
|
+
data.tar.gz: db1fcfbc712fb192783313556324494449c2a74a0f57ce87cad2e72ff4fc7cd4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 89243da73df7ed62d3abfebe75b1391f8c8f3faa767fac3b2b6d448ce32056c337e6aa64fb9bdb0e05c8df0484459837c3813df11e9b7dfeb90c9364477fbf43
|
|
7
|
+
data.tar.gz: d48b6691228d1382242db0f2cd4a63cf65d12ea515eeef34b181322495dd8c78a7b0a5c459dd05bd6b1bc1a48b23b6b7e71742dc2be6c685768abd0eb22606c3
|
data/.github/CODEOWNERS
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: bundler
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: weekly
|
|
7
|
+
day: monday
|
|
8
|
+
open-pull-requests-limit: 5
|
|
9
|
+
labels:
|
|
10
|
+
- "type:dependencies"
|
|
11
|
+
- package-ecosystem: github-actions
|
|
12
|
+
directory: /
|
|
13
|
+
schedule:
|
|
14
|
+
interval: weekly
|
|
15
|
+
day: monday
|
|
16
|
+
open-pull-requests-limit: 5
|
|
17
|
+
labels:
|
|
18
|
+
- "type:dependencies"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: '0 9 * * 1'
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
ci:
|
|
11
|
+
uses: LegionIO/.github/.github/workflows/ci.yml@main
|
|
12
|
+
|
|
13
|
+
excluded-files:
|
|
14
|
+
uses: LegionIO/.github/.github/workflows/excluded-files.yml@main
|
|
15
|
+
|
|
16
|
+
security:
|
|
17
|
+
uses: LegionIO/.github/.github/workflows/security-scan.yml@main
|
|
18
|
+
|
|
19
|
+
version-changelog:
|
|
20
|
+
uses: LegionIO/.github/.github/workflows/version-changelog.yml@main
|
|
21
|
+
|
|
22
|
+
dependency-review:
|
|
23
|
+
uses: LegionIO/.github/.github/workflows/dependency-review.yml@main
|
|
24
|
+
|
|
25
|
+
stale:
|
|
26
|
+
if: github.event_name == 'schedule'
|
|
27
|
+
uses: LegionIO/.github/.github/workflows/stale.yml@main
|
|
28
|
+
|
|
29
|
+
release:
|
|
30
|
+
needs: [ci, excluded-files]
|
|
31
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
32
|
+
uses: LegionIO/.github/.github/workflows/release.yml@main
|
|
33
|
+
secrets:
|
|
34
|
+
rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
|
data/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Gemfile.lock
|
data/.rspec
ADDED
data/.rspec_status
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
example_id | status | run_time |
|
|
2
|
+
----------------------------------------------------------------------- | ------ | --------------- |
|
|
3
|
+
./spec/legion/extensions/nautobot/client_spec.rb[1:1] | passed | 0.03785 seconds |
|
|
4
|
+
./spec/legion/extensions/nautobot/client_spec.rb[1:2] | passed | 0.00758 seconds |
|
|
5
|
+
./spec/legion/extensions/nautobot/client_spec.rb[1:3] | passed | 0.00298 seconds |
|
|
6
|
+
./spec/legion/extensions/nautobot/client_spec.rb[1:4:1] | passed | 0.00043 seconds |
|
|
7
|
+
./spec/legion/extensions/nautobot/runners/circuits_spec.rb[1:1:1] | passed | 0.00508 seconds |
|
|
8
|
+
./spec/legion/extensions/nautobot/runners/circuits_spec.rb[1:2:1] | passed | 0.00064 seconds |
|
|
9
|
+
./spec/legion/extensions/nautobot/runners/circuits_spec.rb[1:3:1] | passed | 0.00443 seconds |
|
|
10
|
+
./spec/legion/extensions/nautobot/runners/circuits_spec.rb[1:4:1] | passed | 0.00061 seconds |
|
|
11
|
+
./spec/legion/extensions/nautobot/runners/circuits_spec.rb[1:5:1] | passed | 0.00052 seconds |
|
|
12
|
+
./spec/legion/extensions/nautobot/runners/circuits_spec.rb[1:5:2] | passed | 0.00042 seconds |
|
|
13
|
+
./spec/legion/extensions/nautobot/runners/circuits_spec.rb[1:6:1] | passed | 0.00054 seconds |
|
|
14
|
+
./spec/legion/extensions/nautobot/runners/cloud_spec.rb[1:1:1] | passed | 0.00097 seconds |
|
|
15
|
+
./spec/legion/extensions/nautobot/runners/cloud_spec.rb[1:2:1] | passed | 0.0005 seconds |
|
|
16
|
+
./spec/legion/extensions/nautobot/runners/cloud_spec.rb[1:3:1] | passed | 0.00044 seconds |
|
|
17
|
+
./spec/legion/extensions/nautobot/runners/cloud_spec.rb[1:4:1] | passed | 0.00053 seconds |
|
|
18
|
+
./spec/legion/extensions/nautobot/runners/cloud_spec.rb[1:5:1] | passed | 0.00058 seconds |
|
|
19
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:1:1] | passed | 0.00049 seconds |
|
|
20
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:1:2] | passed | 0.00046 seconds |
|
|
21
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:1:3] | passed | 0.00306 seconds |
|
|
22
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:2:1] | passed | 0.0005 seconds |
|
|
23
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:3:1] | passed | 0.00061 seconds |
|
|
24
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:3:2] | passed | 0.00051 seconds |
|
|
25
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:4:1] | passed | 0.00063 seconds |
|
|
26
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:4:2] | passed | 0.00099 seconds |
|
|
27
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:5:1] | passed | 0.00121 seconds |
|
|
28
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:5:2] | passed | 0.00055 seconds |
|
|
29
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:6:1] | passed | 0.00059 seconds |
|
|
30
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:7:1] | passed | 0.00056 seconds |
|
|
31
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:8:1] | passed | 0.00658 seconds |
|
|
32
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:9:1] | passed | 0.00043 seconds |
|
|
33
|
+
./spec/legion/extensions/nautobot/runners/dcim_spec.rb[1:10:1] | passed | 0.00038 seconds |
|
|
34
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:1:1] | passed | 0.00084 seconds |
|
|
35
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:2:1] | passed | 0.00021 seconds |
|
|
36
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:3:1] | passed | 0.00019 seconds |
|
|
37
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:4:1] | passed | 0.00018 seconds |
|
|
38
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:4:2] | passed | 0.00044 seconds |
|
|
39
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:5:1] | passed | 0.00018 seconds |
|
|
40
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:6:1] | passed | 0.00017 seconds |
|
|
41
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:7:1] | passed | 0.00015 seconds |
|
|
42
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:8:1] | passed | 0.0003 seconds |
|
|
43
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:9:1] | passed | 0.0003 seconds |
|
|
44
|
+
./spec/legion/extensions/nautobot/runners/extras_spec.rb[1:10:1] | passed | 0.00019 seconds |
|
|
45
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:1:1] | passed | 0.0002 seconds |
|
|
46
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:1:2] | passed | 0.00019 seconds |
|
|
47
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:2:1] | passed | 0.00024 seconds |
|
|
48
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:3:1] | passed | 0.00029 seconds |
|
|
49
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:3:2] | passed | 0.00016 seconds |
|
|
50
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:4:1] | passed | 0.00018 seconds |
|
|
51
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:5:1] | passed | 0.00016 seconds |
|
|
52
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:6:1] | passed | 0.00017 seconds |
|
|
53
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:7:1] | passed | 0.00025 seconds |
|
|
54
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:8:1] | passed | 0.00016 seconds |
|
|
55
|
+
./spec/legion/extensions/nautobot/runners/ipam_spec.rb[1:9:1] | passed | 0.00017 seconds |
|
|
56
|
+
./spec/legion/extensions/nautobot/runners/tenancy_spec.rb[1:1:1] | passed | 0.00019 seconds |
|
|
57
|
+
./spec/legion/extensions/nautobot/runners/tenancy_spec.rb[1:2:1] | passed | 0.00017 seconds |
|
|
58
|
+
./spec/legion/extensions/nautobot/runners/tenancy_spec.rb[1:3:1] | passed | 0.00023 seconds |
|
|
59
|
+
./spec/legion/extensions/nautobot/runners/tenancy_spec.rb[1:3:2] | passed | 0.00015 seconds |
|
|
60
|
+
./spec/legion/extensions/nautobot/runners/tenancy_spec.rb[1:4:1] | passed | 0.00016 seconds |
|
|
61
|
+
./spec/legion/extensions/nautobot/runners/tenancy_spec.rb[1:5:1] | passed | 0.00014 seconds |
|
|
62
|
+
./spec/legion/extensions/nautobot/runners/users_spec.rb[1:1:1] | passed | 0.00014 seconds |
|
|
63
|
+
./spec/legion/extensions/nautobot/runners/users_spec.rb[1:2:1] | passed | 0.00014 seconds |
|
|
64
|
+
./spec/legion/extensions/nautobot/runners/users_spec.rb[1:3:1] | passed | 0.00018 seconds |
|
|
65
|
+
./spec/legion/extensions/nautobot/runners/users_spec.rb[1:4:1] | passed | 0.00014 seconds |
|
|
66
|
+
./spec/legion/extensions/nautobot/runners/users_spec.rb[1:5:1] | passed | 0.00014 seconds |
|
|
67
|
+
./spec/legion/extensions/nautobot/runners/virtualization_spec.rb[1:1:1] | passed | 0.00017 seconds |
|
|
68
|
+
./spec/legion/extensions/nautobot/runners/virtualization_spec.rb[1:2:1] | passed | 0.00016 seconds |
|
|
69
|
+
./spec/legion/extensions/nautobot/runners/virtualization_spec.rb[1:3:1] | passed | 0.00017 seconds |
|
|
70
|
+
./spec/legion/extensions/nautobot/runners/virtualization_spec.rb[1:3:2] | passed | 0.00015 seconds |
|
|
71
|
+
./spec/legion/extensions/nautobot/runners/virtualization_spec.rb[1:4:1] | passed | 0.00021 seconds |
|
|
72
|
+
./spec/legion/extensions/nautobot/runners/virtualization_spec.rb[1:5:1] | passed | 0.00019 seconds |
|
|
73
|
+
./spec/legion/extensions/nautobot/runners/vpn_spec.rb[1:1:1] | passed | 0.00018 seconds |
|
|
74
|
+
./spec/legion/extensions/nautobot/runners/vpn_spec.rb[1:2:1] | passed | 0.00016 seconds |
|
|
75
|
+
./spec/legion/extensions/nautobot/runners/vpn_spec.rb[1:3:1] | passed | 0.00017 seconds |
|
|
76
|
+
./spec/legion/extensions/nautobot/runners/vpn_spec.rb[1:4:1] | passed | 0.00017 seconds |
|
|
77
|
+
./spec/legion/extensions/nautobot/runners/vpn_spec.rb[1:5:1] | passed | 0.00017 seconds |
|
|
78
|
+
./spec/legion/extensions/nautobot/runners/wireless_spec.rb[1:1:1] | passed | 0.00014 seconds |
|
|
79
|
+
./spec/legion/extensions/nautobot/runners/wireless_spec.rb[1:2:1] | passed | 0.00015 seconds |
|
|
80
|
+
./spec/legion/extensions/nautobot/runners/wireless_spec.rb[1:3:1] | passed | 0.00013 seconds |
|
|
81
|
+
./spec/legion/extensions/nautobot/runners/wireless_spec.rb[1:4:1] | passed | 0.00014 seconds |
|
|
82
|
+
./spec/legion/extensions/nautobot_spec.rb[1:1] | passed | 0.00366 seconds |
|
|
83
|
+
./spec/legion/extensions/nautobot_spec.rb[1:2] | passed | 0.00004 seconds |
|
data/.rubocop.yml
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.0] - 2026-05-28
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Initial release
|
|
7
|
+
- DCIM runner (devices, locations, racks, interfaces, cables, manufacturers, platforms, virtual chassis, controllers, software)
|
|
8
|
+
- IPAM runner (prefixes, IP addresses, VLANs, VRFs, namespaces, services, route targets, RIRs)
|
|
9
|
+
- Circuits runner (providers, circuits, circuit types, circuit terminations, provider networks)
|
|
10
|
+
- Tenancy runner (tenants, tenant groups)
|
|
11
|
+
- Virtualization runner (clusters, cluster types, cluster groups, virtual machines, VM interfaces)
|
|
12
|
+
- Extras runner (tags, statuses, roles, custom fields, config contexts, dynamic groups, git repos, jobs, secrets, relationships, webhooks, GraphQL, contacts, teams, external integrations)
|
|
13
|
+
- Users runner (users, groups, tokens, permissions)
|
|
14
|
+
- Cloud runner (cloud accounts, cloud networks, cloud services, cloud resource types)
|
|
15
|
+
- VPN runner (VPNs, VPN tunnels, VPN tunnel endpoints, VPN profiles, VPN terminations)
|
|
16
|
+
- Wireless runner (radio profiles, wireless networks, supported data rates)
|
|
17
|
+
- Standalone Client class with read_only guard
|
|
18
|
+
- Token-based authentication via Faraday
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# lex-nautobot
|
|
2
|
+
|
|
3
|
+
Legion Extension connecting LegionIO to Nautobot — a network source of truth and automation platform. Provides runners for all major Nautobot API apps: DCIM, IPAM, Circuits, Tenancy, Virtualization, Extras, Users, Cloud, VPN, and Wireless.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Legion::Extensions::Nautobot
|
|
9
|
+
├── Runners/
|
|
10
|
+
│ ├── Dcim # Devices, locations, racks, interfaces, cables, manufacturers, platforms, etc.
|
|
11
|
+
│ ├── Ipam # Prefixes, IP addresses, VLANs, VRFs, namespaces, services
|
|
12
|
+
│ ├── Circuits # Providers, circuits, circuit types, terminations
|
|
13
|
+
│ ├── Tenancy # Tenants, tenant groups
|
|
14
|
+
│ ├── Virtualization # Clusters, virtual machines, VM interfaces
|
|
15
|
+
│ ├── Extras # Tags, statuses, jobs, config contexts, git repos, webhooks, GraphQL
|
|
16
|
+
│ ├── Users # Users, groups, tokens, permissions
|
|
17
|
+
│ ├── Cloud # Cloud accounts, networks, services, resource types
|
|
18
|
+
│ ├── Vpn # VPNs, tunnels, endpoints, profiles, terminations
|
|
19
|
+
│ └── Wireless # Radio profiles, wireless networks, data rates
|
|
20
|
+
├── Helpers/Client # Faraday connection (Token auth)
|
|
21
|
+
├── Errors # ReadOnlyError
|
|
22
|
+
└── Client # Standalone client class
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Key Design Decisions
|
|
26
|
+
|
|
27
|
+
- Nautobot uses `Token` auth (not Bearer) — header is `Authorization: Token <token>`
|
|
28
|
+
- Nautobot uses UUIDs for all object IDs
|
|
29
|
+
- API responses use `results` array (paginated) unlike TFE's JSON:API `data` array
|
|
30
|
+
- All endpoints use trailing slashes (Nautobot/Django convention)
|
|
31
|
+
- **Read-Only Guard**: write operations raise `ReadOnlyError` when `read_only: true`
|
|
32
|
+
- No default URL — must be provided (unlike TFE which defaults to app.terraform.io)
|
|
33
|
+
- Depends on `faraday` (>= 2.0)
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 LegionIO
|
|
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.
|
data/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# lex-nautobot
|
|
2
|
+
|
|
3
|
+
Legion Extension for [Nautobot](https://github.com/nautobot/nautobot) — a network source of truth and automation platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
gem 'lex-nautobot'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
client = Legion::Extensions::Nautobot::Client.new(
|
|
15
|
+
url: 'https://nautobot.example.com',
|
|
16
|
+
token: 'your-api-token'
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# DCIM
|
|
20
|
+
client.list_devices
|
|
21
|
+
client.get_device(id: 'uuid')
|
|
22
|
+
client.create_device(name: 'switch-01', device_type: 'uuid', location: 'uuid', status: 'active')
|
|
23
|
+
|
|
24
|
+
# IPAM
|
|
25
|
+
client.list_prefixes
|
|
26
|
+
client.list_ip_addresses(namespace: 'uuid')
|
|
27
|
+
client.create_prefix(prefix: '10.0.0.0/24', namespace: 'uuid', status: 'active')
|
|
28
|
+
|
|
29
|
+
# Circuits
|
|
30
|
+
client.list_circuits
|
|
31
|
+
client.list_providers
|
|
32
|
+
|
|
33
|
+
# Virtualization
|
|
34
|
+
client.list_virtual_machines
|
|
35
|
+
client.list_clusters
|
|
36
|
+
|
|
37
|
+
# Extras
|
|
38
|
+
client.list_jobs
|
|
39
|
+
client.run_job(id: 'job-uuid', data: { key: 'value' })
|
|
40
|
+
client.graphql_query(query: '{ devices { name } }')
|
|
41
|
+
|
|
42
|
+
# Cloud, VPN, Wireless
|
|
43
|
+
client.list_cloud_accounts
|
|
44
|
+
client.list_vpn_tunnels
|
|
45
|
+
client.list_wireless_networks
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Read-Only Mode
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
client = Legion::Extensions::Nautobot::Client.new(
|
|
52
|
+
url: 'https://nautobot.example.com',
|
|
53
|
+
token: 'your-api-token',
|
|
54
|
+
read_only: true
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
client.list_devices # works
|
|
58
|
+
client.create_device(...) # raises ReadOnlyError
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Runners
|
|
62
|
+
|
|
63
|
+
| Runner | Nautobot App | Key Resources |
|
|
64
|
+
|--------|-------------|---------------|
|
|
65
|
+
| Dcim | `/api/dcim/` | devices, locations, racks, interfaces, cables, manufacturers |
|
|
66
|
+
| Ipam | `/api/ipam/` | prefixes, IP addresses, VLANs, VRFs, namespaces |
|
|
67
|
+
| Circuits | `/api/circuits/` | providers, circuits, circuit types, terminations |
|
|
68
|
+
| Tenancy | `/api/tenancy/` | tenants, tenant groups |
|
|
69
|
+
| Virtualization | `/api/virtualization/` | clusters, virtual machines, VM interfaces |
|
|
70
|
+
| Extras | `/api/extras/` | tags, statuses, jobs, config contexts, webhooks, GraphQL |
|
|
71
|
+
| Users | `/api/users/` | users, groups, tokens, permissions |
|
|
72
|
+
| Cloud | `/api/cloud/` | cloud accounts, networks, services |
|
|
73
|
+
| Vpn | `/api/vpn/` | VPNs, tunnels, profiles, terminations |
|
|
74
|
+
| Wireless | `/api/wireless/` | radio profiles, wireless networks |
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/legion/extensions/nautobot/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'lex-nautobot'
|
|
7
|
+
spec.version = Legion::Extensions::Nautobot::VERSION
|
|
8
|
+
spec.authors = ['Matthew Iverson']
|
|
9
|
+
spec.email = ['matthewdiverson@gmail.com']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'LEX Nautobot'
|
|
12
|
+
spec.description = 'Connects LegionIO to Nautobot network source of truth and automation platform'
|
|
13
|
+
spec.homepage = 'https://github.com/LegionIO/lex-nautobot'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
spec.required_ruby_version = '>= 3.4'
|
|
16
|
+
|
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
18
|
+
spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-nautobot'
|
|
19
|
+
spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-nautobot'
|
|
20
|
+
spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-nautobot'
|
|
21
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-nautobot/issues'
|
|
22
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
23
|
+
|
|
24
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
25
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
26
|
+
end
|
|
27
|
+
spec.require_paths = ['lib']
|
|
28
|
+
|
|
29
|
+
spec.add_dependency 'faraday', '>= 2.0'
|
|
30
|
+
spec.add_dependency 'legion-cache', '>= 1.3.11'
|
|
31
|
+
spec.add_dependency 'legion-crypt', '>= 1.4.9'
|
|
32
|
+
spec.add_dependency 'legion-data', '>= 1.4.17'
|
|
33
|
+
spec.add_dependency 'legion-json', '>= 1.2.1'
|
|
34
|
+
spec.add_dependency 'legion-logging', '>= 1.3.2'
|
|
35
|
+
spec.add_dependency 'legion-settings', '>= 1.3.14'
|
|
36
|
+
spec.add_dependency 'legion-transport', '>= 1.3.9'
|
|
37
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/nautobot/helpers/client'
|
|
4
|
+
require 'legion/extensions/nautobot/runners/dcim'
|
|
5
|
+
require 'legion/extensions/nautobot/runners/ipam'
|
|
6
|
+
require 'legion/extensions/nautobot/runners/circuits'
|
|
7
|
+
require 'legion/extensions/nautobot/runners/tenancy'
|
|
8
|
+
require 'legion/extensions/nautobot/runners/virtualization'
|
|
9
|
+
require 'legion/extensions/nautobot/runners/extras'
|
|
10
|
+
require 'legion/extensions/nautobot/runners/users'
|
|
11
|
+
require 'legion/extensions/nautobot/runners/cloud'
|
|
12
|
+
require 'legion/extensions/nautobot/runners/vpn'
|
|
13
|
+
require 'legion/extensions/nautobot/runners/wireless'
|
|
14
|
+
|
|
15
|
+
module Legion
|
|
16
|
+
module Extensions
|
|
17
|
+
module Nautobot
|
|
18
|
+
class Client
|
|
19
|
+
include Helpers::Client
|
|
20
|
+
include Runners::Dcim
|
|
21
|
+
include Runners::Ipam
|
|
22
|
+
include Runners::Circuits
|
|
23
|
+
include Runners::Tenancy
|
|
24
|
+
include Runners::Virtualization
|
|
25
|
+
include Runners::Extras
|
|
26
|
+
include Runners::Users
|
|
27
|
+
include Runners::Cloud
|
|
28
|
+
include Runners::Vpn
|
|
29
|
+
include Runners::Wireless
|
|
30
|
+
|
|
31
|
+
attr_reader :opts
|
|
32
|
+
|
|
33
|
+
def initialize(url:, token: nil, read_only: false, **extra)
|
|
34
|
+
@opts = { url: url, token: token, read_only: read_only, **extra }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def connection(**override)
|
|
38
|
+
super(**@opts.merge(override.compact))
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Nautobot
|
|
8
|
+
module Helpers
|
|
9
|
+
module Client
|
|
10
|
+
def connection(url: nil, token: nil, **_opts)
|
|
11
|
+
Faraday.new(url: url) do |conn|
|
|
12
|
+
conn.request :json
|
|
13
|
+
conn.response :json, content_type: /\bjson$/
|
|
14
|
+
conn.headers['Authorization'] = "Token #{token}" if token
|
|
15
|
+
conn.headers['Content-Type'] = 'application/json'
|
|
16
|
+
conn.headers['Accept'] = 'application/json'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/nautobot/helpers/client'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Nautobot
|
|
8
|
+
module Runners
|
|
9
|
+
module Circuits
|
|
10
|
+
include Legion::Extensions::Nautobot::Helpers::Client
|
|
11
|
+
|
|
12
|
+
# Providers
|
|
13
|
+
def list_providers(url: nil, token: nil, **params)
|
|
14
|
+
resp = connection(url: url, token: token).get('/api/circuits/providers/', params)
|
|
15
|
+
resp.body
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get_provider(id:, url: nil, token: nil, **)
|
|
19
|
+
resp = connection(url: url, token: token).get("/api/circuits/providers/#{id}/")
|
|
20
|
+
resp.body
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def create_provider(url: nil, token: nil, read_only: false, **attrs)
|
|
24
|
+
raise ReadOnlyError, 'Write operations disabled (read_only mode)' if read_only
|
|
25
|
+
|
|
26
|
+
resp = connection(url: url, token: token).post('/api/circuits/providers/', attrs)
|
|
27
|
+
resp.body
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def update_provider(id:, url: nil, token: nil, read_only: false, **attrs)
|
|
31
|
+
raise ReadOnlyError, 'Write operations disabled (read_only mode)' if read_only
|
|
32
|
+
|
|
33
|
+
resp = connection(url: url, token: token).patch("/api/circuits/providers/#{id}/", attrs)
|
|
34
|
+
resp.body
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def delete_provider(id:, url: nil, token: nil, read_only: false, **)
|
|
38
|
+
raise ReadOnlyError, 'Write operations disabled (read_only mode)' if read_only
|
|
39
|
+
|
|
40
|
+
connection(url: url, token: token).delete("/api/circuits/providers/#{id}/")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Provider Networks
|
|
44
|
+
def list_provider_networks(url: nil, token: nil, **params)
|
|
45
|
+
resp = connection(url: url, token: token).get('/api/circuits/provider-networks/', params)
|
|
46
|
+
resp.body
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def get_provider_network(id:, url: nil, token: nil, **)
|
|
50
|
+
resp = connection(url: url, token: token).get("/api/circuits/provider-networks/#{id}/")
|
|
51
|
+
resp.body
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Circuit Types
|
|
55
|
+
def list_circuit_types(url: nil, token: nil, **params)
|
|
56
|
+
resp = connection(url: url, token: token).get('/api/circuits/circuit-types/', params)
|
|
57
|
+
resp.body
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def get_circuit_type(id:, url: nil, token: nil, **)
|
|
61
|
+
resp = connection(url: url, token: token).get("/api/circuits/circuit-types/#{id}/")
|
|
62
|
+
resp.body
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def create_circuit_type(url: nil, token: nil, read_only: false, **attrs)
|
|
66
|
+
raise ReadOnlyError, 'Write operations disabled (read_only mode)' if read_only
|
|
67
|
+
|
|
68
|
+
resp = connection(url: url, token: token).post('/api/circuits/circuit-types/', attrs)
|
|
69
|
+
resp.body
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Circuits
|
|
73
|
+
def list_circuits(url: nil, token: nil, **params)
|
|
74
|
+
resp = connection(url: url, token: token).get('/api/circuits/circuits/', params)
|
|
75
|
+
resp.body
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def get_circuit(id:, url: nil, token: nil, **)
|
|
79
|
+
resp = connection(url: url, token: token).get("/api/circuits/circuits/#{id}/")
|
|
80
|
+
resp.body
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def create_circuit(url: nil, token: nil, read_only: false, **attrs)
|
|
84
|
+
raise ReadOnlyError, 'Write operations disabled (read_only mode)' if read_only
|
|
85
|
+
|
|
86
|
+
resp = connection(url: url, token: token).post('/api/circuits/circuits/', attrs)
|
|
87
|
+
resp.body
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def update_circuit(id:, url: nil, token: nil, read_only: false, **attrs)
|
|
91
|
+
raise ReadOnlyError, 'Write operations disabled (read_only mode)' if read_only
|
|
92
|
+
|
|
93
|
+
resp = connection(url: url, token: token).patch("/api/circuits/circuits/#{id}/", attrs)
|
|
94
|
+
resp.body
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def delete_circuit(id:, url: nil, token: nil, read_only: false, **)
|
|
98
|
+
raise ReadOnlyError, 'Write operations disabled (read_only mode)' if read_only
|
|
99
|
+
|
|
100
|
+
connection(url: url, token: token).delete("/api/circuits/circuits/#{id}/")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Circuit Terminations
|
|
104
|
+
def list_circuit_terminations(url: nil, token: nil, **params)
|
|
105
|
+
resp = connection(url: url, token: token).get('/api/circuits/circuit-terminations/', params)
|
|
106
|
+
resp.body
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def get_circuit_termination(id:, url: nil, token: nil, **)
|
|
110
|
+
resp = connection(url: url, token: token).get("/api/circuits/circuit-terminations/#{id}/")
|
|
111
|
+
resp.body
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def create_circuit_termination(url: nil, token: nil, read_only: false, **attrs)
|
|
115
|
+
raise ReadOnlyError, 'Write operations disabled (read_only mode)' if read_only
|
|
116
|
+
|
|
117
|
+
resp = connection(url: url, token: token).post('/api/circuits/circuit-terminations/', attrs)
|
|
118
|
+
resp.body
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
|
|
122
|
+
Legion::Extensions::Helpers.const_defined?(:Lex, false)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|