-
Notifications
You must be signed in to change notification settings - Fork 190
Added a trace property to the traceable interface classes #280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
af4a35e
0ff839f
c8cc839
74b6e53
d020bcc
c670197
55cacaf
bb5ef86
754633c
cc5210d
0a6e0a8
8d69e4a
d8acca0
c8b91e3
997854f
4a0d8ca
e6d2b78
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,12 +13,56 @@ | |
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| """ | ||
| from six.moves.urllib.parse import urlsplit | ||
|
|
||
| from pynetbox.core.query import Request | ||
| from pynetbox.core.response import Record, JsonField | ||
| from pynetbox.core.endpoint import RODetailEndpoint | ||
| from pynetbox.models.ipam import IpAddresses | ||
| from pynetbox.models.circuits import Circuits | ||
|
|
||
|
|
||
| class TraceableRecord(Record): | ||
| @property | ||
| def trace(self): | ||
| req = Request( | ||
| key=str(self.id) + "/trace" if not self.url else None, | ||
| base=self.endpoint.url, | ||
| token=self.api.token, | ||
| session_key=self.api.session_key, | ||
| http_session=self.api.http_session, | ||
| ) | ||
| ret = [] | ||
| for (termination_a_data, cable_data, termination_b_data) in req.get(): | ||
| this_hop_ret = [] | ||
| for hop_item_data in (termination_a_data, cable_data, termination_b_data): | ||
| # if not fully terminated then some items will be None | ||
| if not hop_item_data: | ||
| this_hop_ret.append(hop_item_data) | ||
| continue | ||
|
|
||
| url_path = urlsplit(hop_item_data["url"]).path | ||
| if url_path.startswith("/api/dcim/cables"): | ||
| return_obj_class = Cables | ||
| elif url_path.startswith("/api/dcim/front-ports"): | ||
| return_obj_class = FrontPorts | ||
| elif url_path.startswith("/api/dcim/interfaces"): | ||
| return_obj_class = Interfaces | ||
| elif url_path.startswith("/api/dcim/rear-ports"): | ||
| return_obj_class = RearPorts | ||
| else: | ||
| raise NotImplementedError( | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this how you would want to handle this situation?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd probably make a dict here that mapped the endpoint name it might encounter with the custom object instead of an if/else tree (really wish switches were a thing in python). e.g. You'll probably want to add some other endpoint/objects you might come across in the traces as well like ConsolePort/ConsoleServerPort and PowerPort/Outlets. I'd probably default to just a simple
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perfect. I'll update to a map and return a |
||
| "unable to unpack item data from endpoint '{}'".format(url_path) | ||
| ) | ||
| this_hop_ret.append( | ||
| return_obj_class(hop_item_data, self.endpoint.api, self.endpoint) | ||
|
raddessi marked this conversation as resolved.
|
||
| ) | ||
|
|
||
| ret.append(this_hop_ret) | ||
|
|
||
| return ret | ||
|
|
||
|
|
||
| class DeviceTypes(Record): | ||
| def __str__(self): | ||
| return self.model | ||
|
|
@@ -80,11 +124,27 @@ class ConnectedEndpoint(Record): | |
| device = Devices | ||
|
|
||
|
|
||
| class Interfaces(Record): | ||
| class Interfaces(TraceableRecord): | ||
| interface_connection = InterfaceConnection | ||
| connected_endpoint = ConnectedEndpoint | ||
|
|
||
|
|
||
| class PowerOutlets(TraceableRecord): | ||
| device = Devices | ||
|
|
||
|
|
||
| class PowerPorts(TraceableRecord): | ||
| device = Devices | ||
|
|
||
|
|
||
| class ConsolePorts(TraceableRecord): | ||
| device = Devices | ||
|
|
||
|
|
||
| class ConsoleServerPorts(TraceableRecord): | ||
| device = Devices | ||
|
|
||
|
|
||
| class RackReservations(Record): | ||
| def __str__(self): | ||
| return self.description | ||
|
|
@@ -99,6 +159,14 @@ class RUs(Record): | |
| device = Devices | ||
|
|
||
|
|
||
| class FrontPorts(Record): | ||
| device = Devices | ||
|
|
||
|
|
||
| class RearPorts(Record): | ||
| device = Devices | ||
|
|
||
|
|
||
| class Racks(Record): | ||
| @property | ||
| def units(self): | ||
|
|
@@ -154,7 +222,21 @@ def __str__(self): | |
|
|
||
| class Cables(Record): | ||
| def __str__(self): | ||
| return "{} <> {}".format(self.termination_a, self.termination_b) | ||
| # populate the terminations to get the full names if they are not already | ||
| try: | ||
| termination_a_name = self.termination_a.name | ||
| except AttributeError: | ||
| self.termination_a.full_details(self) | ||
| termination_a_name = self.termination_a.name | ||
|
|
||
| try: | ||
| termination_b_name = self.termination_b.name | ||
| except AttributeError: | ||
| self.termination_b.full_details(self) | ||
| termination_b_name = self.termination_b.name | ||
|
|
||
|
|
||
| return "{} <> {}".format(termination_a_name, termination_b_name) | ||
|
|
||
| termination_a = Termination | ||
| termination_b = Termination | ||
Uh oh!
There was an error while loading. Please reload this page.