Skip to content

Commit c5af433

Browse files
authored
Merge pull request #907 from rackerlabs/puc-905-nautobot-ansible
feat: PUC-905: moving generic pieces of Nautobot ansible to understack
2 parents c3166ad + 717dd0a commit c5af433

File tree

35 files changed

+989
-4
lines changed

35 files changed

+989
-4
lines changed

.typos.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ extend-exclude = [
66
"schema/argo-workflows.json",
77
"python/understack-workflows/tests/json_samples/",
88
"containers/*/patches",
9-
"go.mod"
9+
"go.mod",
10+
"ansible/roles/statuses/defaults/main.yaml",
1011
]
1112

1213
[default]
@@ -19,3 +20,4 @@ extend-ignore-identifiers-re = [
1920
HPE = "HPE"
2021
fo = "fo"
2122
sme = "sme"
23+
4caf50 = "4caf50"
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
- name: Initial setup of a Nautobot Dev Instance
3+
connection: local
4+
hosts: nautobot
5+
gather_facts: false
6+
7+
# The goal after this playbook runs is to have a set of devices that can
8+
# be tested against. For a Device to be defined in Nautobot you must
9+
# first have a Device Role, a Device Type, and a Rack. For a Device Type
10+
# to be defined you must first have a Manufacturer. For a Rack to be
11+
# defined you must first have a Site. The Rackspace plugin to read
12+
# data from CORE and Location Manager can provide some of these but
13+
# that involves enabling Jobs from our plugin first. To be able to
14+
# run our Jobs we need to populate some Secrets as well.
15+
#
16+
# To visualized linearly we need to instanitate the following:
17+
# - Jobs
18+
# - Secrets
19+
# - Locations
20+
# - Racks
21+
# - Tenants
22+
# - Device Role
23+
# - Manufacturer
24+
# - Device Type
25+
# - Devices
26+
27+
pre_tasks:
28+
- name: Ensure nautobot is up and responding
29+
ansible.builtin.uri:
30+
url: "{{ nautobot_url }}/health/"
31+
method: GET
32+
validate_certs: false
33+
register: nautobot_up_check
34+
until: nautobot_up_check.status == 200
35+
retries: 24 # Retries for 24 * 5 seconds = 120 seconds = 2 minutes
36+
delay: 5 # Every 5 seconds
37+
check_mode: false
38+
39+
roles:
40+
- role: permissions
41+
tags: permissions
42+
- role: jobs
43+
- role: secrets
44+
- role: git_repos
45+
- role: location_types
46+
- role: locations
47+
- role: roles
48+
- role: statuses
49+
- role: custom_fields
50+
- role: computed_fields
51+
- role: platforms
52+
- role: relationships
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# computed fields dynamically create a new field pulling from existing data sources already in Nautobot,
2+
3+
In your variables you'll need to define something like:
4+
5+
```yaml
6+
computed_fields_data:
7+
- key: urn
8+
display: "Device URN"
9+
content_type: dcim.device
10+
label: "Device URN"
11+
description: "A string representing the URN for a device"
12+
template: "{%- if obj.serial and obj.role and obj.location and obj.device_type and obj.device_type.manufacturer %}\n {%- set role = obj.role.name | lower | replace(\" \", \"-\") -%}\n {%- set loc = obj.location.name | lower -%}\n {%- set manufacturer = obj.device_type.manufacturer.name | lower -%}\n {%- set serial = obj.serial | lower -%}\n {%- set partition = \"UC_PARTITION\" | settings_or_config -%}\nurn:rax:undercloud:{{ partition }}:nautobot:{{ role }}:{{ loc }}:{{ manufacturer }}-{{ serial }} {%- endif %}"
13+
weight: 100
14+
advanced_ui: false
15+
```
16+
17+
Where the `key` is the unique slug.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
computed_fields_data: []
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
3+
- name: Check if compute field exists
4+
ansible.builtin.uri:
5+
url: "{{ nautobot_url }}/api/extras/computed-fields/?key={{ item.key }}"
6+
method: GET
7+
body_format: json
8+
headers:
9+
Accept: application/json; version={{ nautobot_api_version }}
10+
Authorization: "Token {{ nautobot_token }}"
11+
register: _computed_field
12+
check_mode: false
13+
14+
- name: Create/update computed fields
15+
ansible.builtin.uri:
16+
url: "{{ nautobot_url }}/api/extras/computed-fields/{{ url_append }}"
17+
method: "{{ method }}"
18+
headers:
19+
Accept: application/json; version={{ nautobot_api_version }}
20+
Authorization: "Token {{ nautobot_token }}"
21+
body_format: json
22+
body: "{{ item }}"
23+
status_code: "{{ status_code }}"
24+
vars:
25+
url_append: "{{ _computed_field.json.results[0].id + '/' if _computed_field.json.count == 1 else '' }}"
26+
method: "{{ 'PATCH' if _computed_field.json.count == 1 else 'POST' }}"
27+
status_code: "{{ 200 if _computed_field.json.count == 1 else 201 }}"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
3+
- name: Define computed fields
4+
ansible.builtin.include_tasks: computed_fields.yml
5+
loop: "{{ computed_fields_data }}"
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
---
2+
3+
custom_field_choices_data:
4+
- value: active
5+
weight: 100
6+
custom_field: ironic_provision_state
7+
state: present
8+
- value: adopting
9+
weight: 100
10+
custom_field: ironic_provision_state
11+
state: present
12+
- value: available
13+
weight: 100
14+
custom_field: ironic_provision_state
15+
state: present
16+
- value: cleaning
17+
weight: 100
18+
custom_field: ironic_provision_state
19+
state: present
20+
- value: clean wait
21+
weight: 100
22+
custom_field: ironic_provision_state
23+
state: present
24+
- value: deleting
25+
weight: 100
26+
custom_field: ironic_provision_state
27+
state: present
28+
- value: deploy failed
29+
weight: 100
30+
custom_field: ironic_provision_state
31+
state: present
32+
- value: deploying
33+
weight: 100
34+
custom_field: ironic_provision_state
35+
state: present
36+
- value: enroll
37+
weight: 100
38+
custom_field: ironic_provision_state
39+
state: present
40+
- value: error
41+
weight: 100
42+
custom_field: ironic_provision_state
43+
state: present
44+
- value: inspect failed
45+
weight: 100
46+
custom_field: ironic_provision_state
47+
state: present
48+
- value: inspecting
49+
weight: 100
50+
custom_field: ironic_provision_state
51+
state: present
52+
- value: inspect wait
53+
weight: 100
54+
custom_field: ironic_provision_state
55+
state: present
56+
- value: manageable
57+
weight: 100
58+
custom_field: ironic_provision_state
59+
state: present
60+
- value: rescue
61+
weight: 100
62+
custom_field: ironic_provision_state
63+
state: present
64+
- value: rescue failed
65+
weight: 100
66+
custom_field: ironic_provision_state
67+
state: present
68+
- value: rescue wait
69+
weight: 100
70+
custom_field: ironic_provision_state
71+
state: present
72+
- value: rescuing
73+
weight: 100
74+
custom_field: ironic_provision_state
75+
state: present
76+
- value: rescuingrescue wait
77+
weight: 100
78+
custom_field: ironic_provision_state
79+
state: present
80+
- value: service failed
81+
weight: 100
82+
custom_field: ironic_provision_state
83+
state: present
84+
- value: service wait
85+
weight: 100
86+
custom_field: ironic_provision_state
87+
state: present
88+
- value: servicing
89+
weight: 100
90+
custom_field: ironic_provision_state
91+
state: present
92+
- value: unrescue failed
93+
weight: 100
94+
custom_field: ironic_provision_state
95+
state: present
96+
- value: unrescuing
97+
weight: 100
98+
custom_field: ironic_provision_state
99+
state: present
100+
- value: verifying
101+
weight: 100
102+
custom_field: ironic_provision_state
103+
state: present
104+
- value: wait call-back
105+
weight: 100
106+
custom_field: ironic_provision_state
107+
state: present
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
3+
- name: Create Custom Field Choices
4+
networktocode.nautobot.custom_field_choice:
5+
url: "{{ nautobot_url }}"
6+
token: "{{ nautobot_token }}"
7+
value: "{{ item.value }}"
8+
weight: "{{ item.weight }}"
9+
custom_field: "{{ item.custom_field }}"
10+
state: present
11+
12+
loop: "{{ custom_field_choices_data }}"
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
- name: Create Custom Field Chassis MAC Address
3+
networktocode.nautobot.custom_field:
4+
state: present
5+
url: "{{ nautobot_url }}"
6+
token: "{{ nautobot_token }}"
7+
description: MAC address advertised to LLDP neighbors (for switches only)
8+
label: Chassis MAC Address
9+
type: text
10+
key: chassis_mac_address
11+
required: false
12+
weight: 100
13+
content_types: dcim.device
14+
filter_logic: exact
15+
validation_regex: ^[0-9A-F][0-9A-F](:[0-9A-F][0-9A-F]){5}$
16+
17+
- name: Create Custom Field DHCP Relay IPv4 Address
18+
networktocode.nautobot.custom_field:
19+
state: present
20+
url: "{{ nautobot_url }}"
21+
token: "{{ nautobot_token }}"
22+
description: >-
23+
For certain interface Roles, configure a "DHCP Helper" service on the
24+
router to forward DHCP requests from locally-connected clients to the
25+
DHCP server specified by this option. The value is an IPv4 address
26+
without the /prefixlen.
27+
label: DHCP Relay IPv4 Address
28+
type: text
29+
key: dhcp_relay_ipv4_address
30+
required: false
31+
weight: 100
32+
content_types:
33+
- dcim.interface
34+
- vni_custom_model.ucvni
35+
validation_regex: ^\d+\.\d+\.\d+\.\d+$
36+
filter_logic: exact
37+
38+
- name: Create Custom Field Tenant VLAN ID
39+
networktocode.nautobot.custom_field:
40+
state: present
41+
url: "{{ nautobot_url }}"
42+
token: "{{ nautobot_token }}"
43+
description: >-
44+
VLAN ID visible to the Tenant, used in the dot1q tag when this VNI
45+
appears on a trunk port. Normally different to the actual VLAN created
46+
on the switch - we use VLAN translation to gives the tenant a consistent
47+
VLAN ID across the whole fabric.
48+
label: Tenant VLAN ID
49+
type: integer
50+
key: tenant_vlan_id
51+
required: false
52+
weight: 100
53+
content_types:
54+
- vni_custom_model.ucvni
55+
validation_minimum: 1
56+
validation_maximum: 4096
57+
filter_logic: exact

ansible/roles/git_repos/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Adding Git Repos
2+
3+
In your variables you'll need to define something like:
4+
5+
```yaml
6+
nb_git_repos:
7+
device_types:
8+
name: Device Types
9+
remote_url: https://github.com/RSS-Engineering/undercloud-nautobot-device-types.git
10+
branch: main
11+
secrets_group: gh_dev_type_pat
12+
```
13+
14+
Where the `key` is the unique slug and the `secrets_group` is the reference to
15+
a `secrets_group` you've defined in the variable `nb_secrets_groups`.

0 commit comments

Comments
 (0)