1
1
import argparse
2
2
import logging
3
3
import uuid
4
+ from collections .abc import Sequence
4
5
from enum import StrEnum
6
+ from typing import cast
7
+
8
+ import pynautobot
9
+ from pynautobot .core .response import Record
5
10
6
11
from understack_workflows .helpers import credential
7
12
from understack_workflows .helpers import parser_nautobot_args
8
13
from understack_workflows .helpers import setup_logger
9
- from understack_workflows .nautobot import Nautobot
10
14
from understack_workflows .openstack .client import Connection
11
15
from understack_workflows .openstack .client import get_openstack_client
12
16
@@ -109,15 +113,24 @@ def _tenant_attrs(conn: Connection, project_id: uuid.UUID) -> tuple[str, str, bo
109
113
return tenant_name , str (project .description ), is_default_domain
110
114
111
115
116
+ def _unmap_tenant_from_devices (
117
+ tenant_id : uuid .UUID ,
118
+ nautobot : pynautobot .api ,
119
+ ):
120
+ devices : Sequence [Record ] = list (nautobot .dcim .devices .filter (tenant = tenant_id ))
121
+ for d in devices :
122
+ d .tenant = None # type: ignore[attr-defined]
123
+ nautobot .dcim .devices .update (devices )
124
+
125
+
112
126
def handle_project_create (
113
- conn : Connection , nautobot : Nautobot , project_id : uuid .UUID
127
+ conn : Connection , nautobot : pynautobot . api , project_id : uuid .UUID
114
128
) -> int :
115
129
logger .info ("got request to create tenant %s" , project_id .hex )
116
130
tenant_name , tenant_description , is_default_domain = _tenant_attrs (conn , project_id )
117
131
118
- nautobot_tenant_api = nautobot .session .tenancy .tenants
119
132
try :
120
- tenant = nautobot_tenant_api .create (
133
+ tenant = nautobot . tenancy . tenants .create (
121
134
id = str (project_id ), name = tenant_name , description = tenant_description
122
135
)
123
136
if is_default_domain :
@@ -133,24 +146,24 @@ def handle_project_create(
133
146
134
147
135
148
def handle_project_update (
136
- conn : Connection , nautobot : Nautobot , project_id : uuid .UUID
149
+ conn : Connection , nautobot : pynautobot . api , project_id : uuid .UUID
137
150
) -> int :
138
151
logger .info ("got request to update tenant %s" , project_id .hex )
139
152
tenant_name , tenant_description , is_default_domain = _tenant_attrs (conn , project_id )
140
153
141
- tenant_api = nautobot .session .tenancy .tenants
142
- existing_tenant = tenant_api .get (project_id )
154
+ existing_tenant = nautobot .tenancy .tenants .get (id = project_id )
143
155
logger .info ("existing_tenant: %s" , existing_tenant )
144
156
try :
145
157
if existing_tenant is None :
146
- new_tenant = tenant_api .create (
158
+ new_tenant = nautobot . tenancy . tenants .create (
147
159
id = str (project_id ), name = tenant_name , description = tenant_description
148
160
)
149
161
logger .info ("tenant %s created %s" , project_id , new_tenant .created ) # type: ignore
150
162
else :
151
- existing_tenant .name = tenant_name # type: ignore
152
- existing_tenant .description = tenant_description # type: ignore
153
- existing_tenant .save () # type: ignore
163
+ existing_tenant = cast (Record , existing_tenant )
164
+ existing_tenant .update (
165
+ {"name" : tenant_name , "description" : tenant_description }
166
+ ) # type: ignore
154
167
logger .info (
155
168
"tenant %s last updated %s" ,
156
169
project_id ,
@@ -168,23 +181,26 @@ def handle_project_update(
168
181
169
182
170
183
def handle_project_delete (
171
- conn : Connection , nautobot : Nautobot , project_id : uuid .UUID
184
+ conn : Connection , nautobot : pynautobot . api , project_id : uuid .UUID
172
185
) -> int :
173
186
logger .info ("got request to delete tenant %s" , project_id )
174
- ten = nautobot .session . tenancy .tenants .get (project_id )
175
- if not ten :
187
+ tenant = nautobot .tenancy .tenants .get (id = project_id )
188
+ if not tenant :
176
189
logger .warning ("tenant %s does not exist, nothing to delete" , project_id )
177
190
return _EXIT_SUCCESS
178
191
179
192
_delete_outside_network (conn , project_id )
180
- ten .delete () # type: ignore
193
+ _unmap_tenant_from_devices (tenant_id = project_id , nautobot = nautobot )
194
+
195
+ tenant = cast (Record , tenant )
196
+ tenant .delete ()
181
197
logger .info ("deleted tenant %s" , project_id )
182
198
return _EXIT_SUCCESS
183
199
184
200
185
201
def do_action (
186
202
conn : Connection ,
187
- nautobot : Nautobot ,
203
+ nautobot : pynautobot . api ,
188
204
event : Event ,
189
205
project_id : uuid .UUID ,
190
206
) -> int :
@@ -206,6 +222,5 @@ def main() -> int:
206
222
207
223
conn = get_openstack_client (cloud = args .os_cloud )
208
224
nb_token = args .nautobot_token or credential ("nb-token" , "token" )
209
- nautobot = Nautobot (args .nautobot_url , nb_token , logger = logger )
210
-
225
+ nautobot = pynautobot .api (args .nautobot_url , token = nb_token )
211
226
return do_action (conn , nautobot , args .event , args .object )
0 commit comments