From 8546c705528da67a79320c587064710d3655ee97 Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Wed, 11 Jun 2025 11:24:53 -0300 Subject: [PATCH 01/18] feat: add DiodeDryRunClient --- netboxlabs/diode/sdk/__init__.py | 4 +- netboxlabs/diode/sdk/client.py | 104 ++++++++++++++++++++++++++++++- tests/test_client.py | 30 +++++++++ 3 files changed, 136 insertions(+), 2 deletions(-) diff --git a/netboxlabs/diode/sdk/__init__.py b/netboxlabs/diode/sdk/__init__.py index c499df8..54830f1 100644 --- a/netboxlabs/diode/sdk/__init__.py +++ b/netboxlabs/diode/sdk/__init__.py @@ -2,6 +2,8 @@ # Copyright 2024 NetBox Labs Inc """NetBox Labs, Diode - SDK.""" -from netboxlabs.diode.sdk.client import DiodeClient +from netboxlabs.diode.sdk.client import DiodeClient, DiodeClientInterface, DiodeDryRunClient +assert DiodeClientInterface assert DiodeClient +assert DiodeDryRunClient diff --git a/netboxlabs/diode/sdk/client.py b/netboxlabs/diode/sdk/client.py index 3c650f1..4e9a129 100644 --- a/netboxlabs/diode/sdk/client.py +++ b/netboxlabs/diode/sdk/client.py @@ -9,13 +9,16 @@ import os import platform import ssl +import sys import uuid from collections.abc import Iterable +from typing import Protocol, runtime_checkable from urllib.parse import urlencode, urlparse import certifi import grpc import sentry_sdk +from google.protobuf.json_format import MessageToDict from netboxlabs.diode.sdk.diode.v1 import ingester_pb2, ingester_pb2_grpc from netboxlabs.diode.sdk.exceptions import DiodeClientError, DiodeConfigError @@ -27,11 +30,38 @@ _DIODE_SENTRY_DSN_ENVVAR_NAME = "DIODE_SENTRY_DSN" _CLIENT_ID_ENVVAR_NAME = "DIODE_CLIENT_ID" _CLIENT_SECRET_ENVVAR_NAME = "DIODE_CLIENT_SECRET" +_DRY_RUN_OUTPUT_ENVVAR_NAME = "DIODE_DRY_RUN_OUTPUT_FILE" _INGEST_SCOPE = "diode:ingest" _DEFAULT_STREAM = "latest" _LOGGER = logging.getLogger(__name__) +@runtime_checkable +class DiodeClientInterface(Protocol): + """Interface implemented by diode clients.""" + + @property + def app_name(self) -> str: + """Name of the producer application.""" + + @property + def version(self) -> str: + """Version of the SDK.""" + + def ingest( + self, + entities: Iterable[Entity | ingester_pb2.Entity | None], + stream: str | None = _DEFAULT_STREAM, + ) -> ingester_pb2.IngestResponse: + """Ingest entities.""" + + def __enter__(self): + """Enters the runtime context related to the channel object.""" + + def __exit__(self, exc_type, exc_value, exc_traceback): + """Exits the runtime context related to the channel object.""" + + def _load_certs() -> bytes: """Loads cacert.pem.""" with open(certifi.where(), "rb") as f: @@ -82,7 +112,7 @@ def _get_optional_config_value( return value -class DiodeClient: +class DiodeClient(DiodeClientInterface): """Diode Client.""" _name = "diode-sdk-python" @@ -287,6 +317,78 @@ def _authenticate(self, scope: str): ) + [("authorization", f"Bearer {access_token}")] +class DiodeDryRunClient(DiodeClientInterface): + """Client that outputs ingestion requests instead of sending them.""" + + _name = "diode-sdk-python-dry-run" + _version = version_semver() + _app_name = None + _app_version = None + + def __init__( + self, app_name: str, app_version: str, dry_run_output_file: str | None = None + ): + """Initiate a new dry run client.""" + self._app_name = app_name + self._app_version = app_version + self._dry_run_output_file = os.getenv( + _DRY_RUN_OUTPUT_ENVVAR_NAME, dry_run_output_file + ) + + @property + def name(self) -> str: + """Retrieve the name.""" + return self._name + + @property + def version(self) -> str: + """Retrieve the version.""" + return self._version + + @property + def app_name(self) -> str: + """Retrieve the app name.""" + return self._app_name + + @property + def app_version(self) -> str: + """Retrieve the app version.""" + return self._app_version + + @property + def dry_run_output_file(self) -> str | None: + """Retrieve the dry run output file.""" + return self._dry_run_output_file + + def __enter__(self): + """Enters the runtime context related to the channel object.""" + return self + + def ingest( + self, + entities: Iterable[Entity | ingester_pb2.Entity | None], + stream: str | None = _DEFAULT_STREAM, + ) -> ingester_pb2.IngestResponse: + """Ingest entities in dry run mode.""" + request = ingester_pb2.IngestRequest( + stream=stream, + id=str(uuid.uuid4()), + entities=entities, + sdk_name=self.name, + sdk_version=self.version, + producer_app_name=self.app_name, + producer_app_version=self.app_version, + ) + + output = json.dumps(MessageToDict(request)) + if self._dry_run_output_file: + with open(self._dry_run_output_file, "a") as fh: + fh.write(output + "\n") + else: + print(output, file=sys.stdout) + return ingester_pb2.IngestResponse() + + class _DiodeAuthentication: def __init__( self, diff --git a/tests/test_client.py b/tests/test_client.py index 7af797d..7447aa4 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -13,6 +13,7 @@ from netboxlabs.diode.sdk.client import ( _DIODE_SENTRY_DSN_ENVVAR_NAME, DiodeClient, + DiodeDryRunClient, DiodeMethodClientInterceptor, _ClientCallDetails, _DiodeAuthentication, @@ -635,3 +636,32 @@ def test_diode_authentication_request_exception(mock_diode_authentication): auth.authenticate() assert "Failed to obtain access token: Connection error" in str(excinfo.value) +def test_ingest_dry_run_stdout(capsys): + """Verify ingest prints JSON when dry run is enabled.""" + client = DiodeDryRunClient( + app_name="my-producer", + app_version="0.0.1", + ) + + client._stub = MagicMock() + client.ingest(entities=[]) + + captured = capsys.readouterr() + assert client._stub.Ingest.call_count == 0 + assert captured.out.startswith("{") + + +def test_ingest_dry_run_file(tmp_path): + """Verify ingest writes JSON to file when dry run output file is set.""" + output_file = tmp_path / "out.json" + client = DiodeDryRunClient( + app_name="my-producer", + app_version="0.0.1", + dry_run_output_file=str(output_file), + ) + + client._stub = MagicMock() + client.ingest(entities=[]) + + assert client._stub.Ingest.call_count == 0 + assert output_file.read_text().startswith("{") From 7bad0390484500b0245fce534feb58d6876b89d7 Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Wed, 11 Jun 2025 11:38:16 -0300 Subject: [PATCH 02/18] cleanup --- netboxlabs/diode/sdk/client.py | 20 +++----------------- tests/test_client.py | 7 +------ 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/netboxlabs/diode/sdk/client.py b/netboxlabs/diode/sdk/client.py index 4e9a129..132f180 100644 --- a/netboxlabs/diode/sdk/client.py +++ b/netboxlabs/diode/sdk/client.py @@ -41,8 +41,8 @@ class DiodeClientInterface(Protocol): """Interface implemented by diode clients.""" @property - def app_name(self) -> str: - """Name of the producer application.""" + def name(self) -> str: + """Name of the SDK.""" @property def version(self) -> str: @@ -326,11 +326,9 @@ class DiodeDryRunClient(DiodeClientInterface): _app_version = None def __init__( - self, app_name: str, app_version: str, dry_run_output_file: str | None = None + self, dry_run_output_file: str | None = None ): """Initiate a new dry run client.""" - self._app_name = app_name - self._app_version = app_version self._dry_run_output_file = os.getenv( _DRY_RUN_OUTPUT_ENVVAR_NAME, dry_run_output_file ) @@ -345,16 +343,6 @@ def version(self) -> str: """Retrieve the version.""" return self._version - @property - def app_name(self) -> str: - """Retrieve the app name.""" - return self._app_name - - @property - def app_version(self) -> str: - """Retrieve the app version.""" - return self._app_version - @property def dry_run_output_file(self) -> str | None: """Retrieve the dry run output file.""" @@ -376,8 +364,6 @@ def ingest( entities=entities, sdk_name=self.name, sdk_version=self.version, - producer_app_name=self.app_name, - producer_app_version=self.app_version, ) output = json.dumps(MessageToDict(request)) diff --git a/tests/test_client.py b/tests/test_client.py index 7447aa4..5e270a8 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -638,10 +638,7 @@ def test_diode_authentication_request_exception(mock_diode_authentication): def test_ingest_dry_run_stdout(capsys): """Verify ingest prints JSON when dry run is enabled.""" - client = DiodeDryRunClient( - app_name="my-producer", - app_version="0.0.1", - ) + client = DiodeDryRunClient() client._stub = MagicMock() client.ingest(entities=[]) @@ -655,8 +652,6 @@ def test_ingest_dry_run_file(tmp_path): """Verify ingest writes JSON to file when dry run output file is set.""" output_file = tmp_path / "out.json" client = DiodeDryRunClient( - app_name="my-producer", - app_version="0.0.1", dry_run_output_file=str(output_file), ) From aa8d275d36dae29df17cbf7de82786217905f2ac Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Wed, 11 Jun 2025 11:54:41 -0300 Subject: [PATCH 03/18] move interface to pyi --- netboxlabs/diode/sdk/client.py | 27 +++------------------------ netboxlabs/diode/sdk/client.pyi | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 netboxlabs/diode/sdk/client.pyi diff --git a/netboxlabs/diode/sdk/client.py b/netboxlabs/diode/sdk/client.py index 132f180..eedc573 100644 --- a/netboxlabs/diode/sdk/client.py +++ b/netboxlabs/diode/sdk/client.py @@ -12,7 +12,6 @@ import sys import uuid from collections.abc import Iterable -from typing import Protocol, runtime_checkable from urllib.parse import urlencode, urlparse import certifi @@ -36,30 +35,10 @@ _LOGGER = logging.getLogger(__name__) -@runtime_checkable -class DiodeClientInterface(Protocol): - """Interface implemented by diode clients.""" +class DiodeClientInterface: + """Runtime placeholder for the Diode client interface.""" - @property - def name(self) -> str: - """Name of the SDK.""" - - @property - def version(self) -> str: - """Version of the SDK.""" - - def ingest( - self, - entities: Iterable[Entity | ingester_pb2.Entity | None], - stream: str | None = _DEFAULT_STREAM, - ) -> ingester_pb2.IngestResponse: - """Ingest entities.""" - - def __enter__(self): - """Enters the runtime context related to the channel object.""" - - def __exit__(self, exc_type, exc_value, exc_traceback): - """Exits the runtime context related to the channel object.""" + pass def _load_certs() -> bytes: diff --git a/netboxlabs/diode/sdk/client.pyi b/netboxlabs/diode/sdk/client.pyi new file mode 100644 index 0000000..16deeaf --- /dev/null +++ b/netboxlabs/diode/sdk/client.pyi @@ -0,0 +1,25 @@ +from __future__ import annotations + +from collections.abc import Iterable +from typing import Protocol, runtime_checkable + +from netboxlabs.diode.sdk.diode.v1 import ingester_pb2 +from netboxlabs.diode.sdk.ingester import Entity + +_DEFAULT_STREAM: str + +@runtime_checkable +class DiodeClientInterface(Protocol): + """Interface implemented by diode clients.""" + + @property + def name(self) -> str: ... + @property + def version(self) -> str: ... + def ingest( + self, + entities: Iterable[Entity | ingester_pb2.Entity | None], + stream: str | None = _DEFAULT_STREAM, + ) -> ingester_pb2.IngestResponse: ... + def __enter__(self) -> DiodeClientInterface: ... + def __exit__(self, exc_type, exc_value, exc_traceback) -> None: ... From 49df7eadd31b93741c60b3d89ca7fdd31ff64c1e Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:30:53 -0300 Subject: [PATCH 04/18] add helper load_dryrun_entities --- netboxlabs/diode/sdk/__init__.py | 8 ++++++-- netboxlabs/diode/sdk/client.py | 21 +++++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/netboxlabs/diode/sdk/__init__.py b/netboxlabs/diode/sdk/__init__.py index 54830f1..89a22e9 100644 --- a/netboxlabs/diode/sdk/__init__.py +++ b/netboxlabs/diode/sdk/__init__.py @@ -2,8 +2,12 @@ # Copyright 2024 NetBox Labs Inc """NetBox Labs, Diode - SDK.""" -from netboxlabs.diode.sdk.client import DiodeClient, DiodeClientInterface, DiodeDryRunClient +from netboxlabs.diode.sdk.client import ( + DiodeClient, + DiodeDryRunClient, + load_dryrun_entities, +) -assert DiodeClientInterface assert DiodeClient assert DiodeDryRunClient +assert load_dryrun_entities diff --git a/netboxlabs/diode/sdk/client.py b/netboxlabs/diode/sdk/client.py index eedc573..ee772cc 100644 --- a/netboxlabs/diode/sdk/client.py +++ b/netboxlabs/diode/sdk/client.py @@ -12,12 +12,13 @@ import sys import uuid from collections.abc import Iterable +from pathlib import Path from urllib.parse import urlencode, urlparse import certifi import grpc import sentry_sdk -from google.protobuf.json_format import MessageToDict +from google.protobuf.json_format import MessageToDict, ParseDict from netboxlabs.diode.sdk.diode.v1 import ingester_pb2, ingester_pb2_grpc from netboxlabs.diode.sdk.exceptions import DiodeClientError, DiodeConfigError @@ -35,6 +36,17 @@ _LOGGER = logging.getLogger(__name__) +def load_dryrun_entities(file_path: str | Path) -> Iterable[Entity]: + """Yield entities stored in a JSON Lines file produced by ``DiodeDryRunClient``.""" + with open(file_path) as fh: + for line in fh: + data = json.loads(line) + for entity_dict in data.get("entities", []): + pb_entity = Entity() + ParseDict(entity_dict, pb_entity) + yield pb_entity + + class DiodeClientInterface: """Runtime placeholder for the Diode client interface.""" @@ -304,9 +316,7 @@ class DiodeDryRunClient(DiodeClientInterface): _app_name = None _app_version = None - def __init__( - self, dry_run_output_file: str | None = None - ): + def __init__(self, dry_run_output_file: str | None = None): """Initiate a new dry run client.""" self._dry_run_output_file = os.getenv( _DRY_RUN_OUTPUT_ENVVAR_NAME, dry_run_output_file @@ -331,6 +341,9 @@ def __enter__(self): """Enters the runtime context related to the channel object.""" return self + def __exit__(self, exc_type, exc_value, exc_traceback): + """Exits the runtime context related to the channel object.""" + def ingest( self, entities: Iterable[Entity | ingester_pb2.Entity | None], From 7b7a0caf6fed3c02e22b981d6d43718c38a9d4c5 Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:54:28 -0300 Subject: [PATCH 05/18] add unit test for load_dryrun_entities --- tests/test_client.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_client.py b/tests/test_client.py index 5e270a8..e23471a 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -20,8 +20,11 @@ _get_sentry_dsn, _load_certs, parse_target, + load_dryrun_entities, ) from netboxlabs.diode.sdk.exceptions import DiodeClientError, DiodeConfigError +from netboxlabs.diode.sdk.ingester import Entity +from netboxlabs.diode.sdk.diode.v1.ingester_pb2 import Entity as EntityPb from netboxlabs.diode.sdk.version import version_semver @@ -660,3 +663,18 @@ def test_ingest_dry_run_file(tmp_path): assert client._stub.Ingest.call_count == 0 assert output_file.read_text().startswith("{") + +def test_load_dryrun_entities(tmp_path): + """Verify ``load_dryrun_entities`` yields protobuf entities.""" + output_file = tmp_path / "dryrun.jsonl" + client = DiodeDryRunClient(dry_run_output_file=str(output_file)) + + client.ingest(entities=[Entity(site="Site1"), Entity(device="Device1")]) + + entities = list(load_dryrun_entities(output_file)) + + assert len(entities) == 2 + assert isinstance(entities[0], EntityPb) + assert entities[0].site.name == "Site1" + assert isinstance(entities[1], EntityPb) + assert entities[1].device.name == "Device1" \ No newline at end of file From 57b191e9d530fdff81f0679c4f3ee3d96cf8e2f9 Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:56:40 -0300 Subject: [PATCH 06/18] ruff fix --- tests/test_client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index e23471a..da9ebda 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -19,12 +19,12 @@ _DiodeAuthentication, _get_sentry_dsn, _load_certs, - parse_target, load_dryrun_entities, + parse_target, ) +from netboxlabs.diode.sdk.diode.v1.ingester_pb2 import Entity as EntityPb from netboxlabs.diode.sdk.exceptions import DiodeClientError, DiodeConfigError from netboxlabs.diode.sdk.ingester import Entity -from netboxlabs.diode.sdk.diode.v1.ingester_pb2 import Entity as EntityPb from netboxlabs.diode.sdk.version import version_semver @@ -677,4 +677,4 @@ def test_load_dryrun_entities(tmp_path): assert isinstance(entities[0], EntityPb) assert entities[0].site.name == "Site1" assert isinstance(entities[1], EntityPb) - assert entities[1].device.name == "Device1" \ No newline at end of file + assert entities[1].device.name == "Device1" From 028386d2d83973829849eebd5420ebcdf070fadf Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:59:11 -0300 Subject: [PATCH 07/18] fix import --- tests/test_client.py | 73 +++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index da9ebda..39aefa2 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -22,7 +22,7 @@ load_dryrun_entities, parse_target, ) -from netboxlabs.diode.sdk.diode.v1.ingester_pb2 import Entity as EntityPb +from netboxlabs.diode.sdk.diode.v1 import ingester_pb2 from netboxlabs.diode.sdk.exceptions import DiodeClientError, DiodeConfigError from netboxlabs.diode.sdk.ingester import Entity from netboxlabs.diode.sdk.version import version_semver @@ -64,7 +64,9 @@ def test_config_errors(client_id, client_secret, env_var_name): client_id=client_id, client_secret=client_secret, ) - assert str(err.value) == f"parameter or {env_var_name} environment variable required" + assert ( + str(err.value) == f"parameter or {env_var_name} environment variable required" + ) def test_client_error(mock_diode_authentication): @@ -90,7 +92,10 @@ def test_diode_client_error_repr_returns_correct_string(): error = DiodeClientError(grpc_error) error._status_code = grpc.StatusCode.UNAVAILABLE error._details = "Some details about the error" - assert repr(error) == "" + assert ( + repr(error) + == "" + ) def test_load_certs_returns_bytes(): @@ -180,7 +185,9 @@ def test_setup_sentry_initializes_with_correct_parameters(mock_diode_authenticat ) -def test_client_sets_up_secure_channel_when_grpcs_scheme_is_found_in_target(mock_diode_authentication): +def test_client_sets_up_secure_channel_when_grpcs_scheme_is_found_in_target( + mock_diode_authentication, +): """Check that DiodeClient.__init__() sets up the gRPC secure channel when grpcs:// scheme is found in the target.""" client = DiodeClient( target="grpcs://localhost:8081", @@ -205,7 +212,9 @@ def test_client_sets_up_secure_channel_when_grpcs_scheme_is_found_in_target(mock mock_secure_channel.assert_called_once() -def test_client_sets_up_insecure_channel_when_grpc_scheme_is_found_in_target(mock_diode_authentication): +def test_client_sets_up_insecure_channel_when_grpc_scheme_is_found_in_target( + mock_diode_authentication, +): """Check that DiodeClient.__init__() sets up the gRPC insecure channel when grpc:// scheme is found in the target.""" client = DiodeClient( target="grpc://localhost:8081", @@ -347,10 +356,14 @@ def test_client_setup_sentry_called_when_sentry_dsn_exists(mock_diode_authentica client_secret="123456", sentry_dsn="https://user@password.mock.dsn/123456", ) - mock_setup_sentry.assert_called_once_with("https://user@password.mock.dsn/123456", 1.0, 1.0) + mock_setup_sentry.assert_called_once_with( + "https://user@password.mock.dsn/123456", 1.0, 1.0 + ) -def test_client_setup_sentry_not_called_when_sentry_dsn_not_exists(mock_diode_authentication): +def test_client_setup_sentry_not_called_when_sentry_dsn_not_exists( + mock_diode_authentication, +): """Check that DiodeClient._setup_sentry() is not called when sentry_dsn does not exist.""" client = DiodeClient( target="grpc://localhost:8081", @@ -471,7 +484,10 @@ def continuation(x, _): None, ) request = None - assert interceptor.intercept_unary_unary(continuation, client_call_details, request) == "/my/path/diode.v1.IngesterService/Ingest" + assert ( + interceptor.intercept_unary_unary(continuation, client_call_details, request) + == "/my/path/diode.v1.IngesterService/Ingest" + ) def test_interceptor_intercepts_stream_unary_calls(): @@ -491,7 +507,9 @@ def continuation(x, _): ) request_iterator = None assert ( - interceptor.intercept_stream_unary(continuation, client_call_details, request_iterator) + interceptor.intercept_stream_unary( + continuation, client_call_details, request_iterator + ) == "/my/path/diode.v1.IngesterService/Ingest" ) @@ -569,7 +587,9 @@ def test_diode_authentication_success(mock_diode_authentication): with mock.patch("http.client.HTTPConnection") as mock_http_conn: mock_conn_instance = mock_http_conn.return_value mock_conn_instance.getresponse.return_value.status = 200 - mock_conn_instance.getresponse.return_value.read.return_value = json.dumps({"access_token": "mocked_token"}).encode() + mock_conn_instance.getresponse.return_value.read.return_value = json.dumps( + {"access_token": "mocked_token"} + ).encode() token = auth.authenticate() assert token == "mocked_token" @@ -595,14 +615,17 @@ def test_diode_authentication_failure(mock_diode_authentication): assert "Failed to obtain access token" in str(excinfo.value) -@pytest.mark.parametrize("path", [ - "/diode", - "", - None, - "/diode/", - "diode", - "diode/", - ]) +@pytest.mark.parametrize( + "path", + [ + "/diode", + "", + None, + "/diode/", + "diode", + "diode/", + ], +) def test_diode_authentication_url_with_path(mock_diode_authentication, path): """Test that the authentication URL is correctly formatted with a path.""" auth = _DiodeAuthentication( @@ -616,9 +639,13 @@ def test_diode_authentication_url_with_path(mock_diode_authentication, path): with mock.patch("http.client.HTTPConnection") as mock_http_conn: mock_conn_instance = mock_http_conn.return_value mock_conn_instance.getresponse.return_value.status = 200 - mock_conn_instance.getresponse.return_value.read.return_value = json.dumps({"access_token": "mocked_token"}).encode() + mock_conn_instance.getresponse.return_value.read.return_value = json.dumps( + {"access_token": "mocked_token"} + ).encode() auth.authenticate() - mock_conn_instance.request.assert_called_once_with("POST", f"{(path or '').rstrip('/')}/auth/token", mock.ANY, mock.ANY) + mock_conn_instance.request.assert_called_once_with( + "POST", f"{(path or '').rstrip('/')}/auth/token", mock.ANY, mock.ANY + ) def test_diode_authentication_request_exception(mock_diode_authentication): @@ -639,6 +666,7 @@ def test_diode_authentication_request_exception(mock_diode_authentication): auth.authenticate() assert "Failed to obtain access token: Connection error" in str(excinfo.value) + def test_ingest_dry_run_stdout(capsys): """Verify ingest prints JSON when dry run is enabled.""" client = DiodeDryRunClient() @@ -664,6 +692,7 @@ def test_ingest_dry_run_file(tmp_path): assert client._stub.Ingest.call_count == 0 assert output_file.read_text().startswith("{") + def test_load_dryrun_entities(tmp_path): """Verify ``load_dryrun_entities`` yields protobuf entities.""" output_file = tmp_path / "dryrun.jsonl" @@ -674,7 +703,7 @@ def test_load_dryrun_entities(tmp_path): entities = list(load_dryrun_entities(output_file)) assert len(entities) == 2 - assert isinstance(entities[0], EntityPb) + assert isinstance(entities[0], ingester_pb2.Entity) assert entities[0].site.name == "Site1" - assert isinstance(entities[1], EntityPb) + assert isinstance(entities[1], ingester_pb2.Entity) assert entities[1].device.name == "Device1" From 1df7be00f21e8358c6d7e0a14710822b839eced5 Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Wed, 11 Jun 2025 15:12:58 -0300 Subject: [PATCH 08/18] docs: document dry run usage (#51) --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index 10119ce..e1f180f 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ pip install netboxlabs-diode-sdk * `DIODE_SENTRY_DSN` - Optional Sentry DSN for error reporting * `DIODE_CLIENT_ID` - Client ID for OAuth2 authentication * `DIODE_CLIENT_SECRET` - Client Secret for OAuth2 authentication +* `DIODE_DRY_RUN_OUTPUT_FILE` - Path to store JSON Lines output when using `DiodeDryRunClient` ### Example @@ -75,6 +76,35 @@ if __name__ == "__main__": ``` +### Dry run mode + +`DiodeDryRunClient` allows generating ingestion requests without contacting a +Diode server. Each request is printed to stdout or written to a JSON Lines file +when `dry_run_output_file` (or `DIODE_DRY_RUN_OUTPUT_FILE`) is set. + +```python +from netboxlabs.diode.sdk import DiodeDryRunClient + +with DiodeDryRunClient(dry_run_output_file="dryrun.jsonl") as client: + client.ingest([ + Entity(device="Device A"), + ]) +``` + +The produced file can later be ingested by a real Diode instance using +`load_dryrun_entities` with a standard `DiodeClient`: + +```python +from netboxlabs.diode.sdk import DiodeClient, load_dryrun_entities + +with DiodeClient( + target="grpc://localhost:8080/diode", + app_name="my-test-app", + app_version="0.0.1", +) as client: + client.ingest(entities=load_dryrun_entities("dryrun.jsonl")) +``` + ## Supported entities (object types) * ASN From 9ecbd5dbb6f67472fdef578400065e322f311248 Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Thu, 12 Jun 2025 13:38:36 -0300 Subject: [PATCH 09/18] Use Message to Json --- README.md | 30 ++++++++++++++++++++++++++++++ netboxlabs/diode/sdk/client.py | 31 +++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e1f180f..f783215 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,36 @@ when `dry_run_output_file` (or `DIODE_DRY_RUN_OUTPUT_FILE`) is set. ```python from netboxlabs.diode.sdk import DiodeDryRunClient +with DiodeDryRunClient(dry_run_output_file="dryrun.json") as client: + client.ingest([ + Entity(device="Device A"), + ]) +``` + +The produced file can later be ingested by a real Diode instance using +`load_dryrun_entities` with a standard `DiodeClient`: + +```python +from netboxlabs.diode.sdk import DiodeClient, load_dryrun_entities + +with DiodeClient( + target="grpc://localhost:8080/diode", + app_name="my-test-app", + app_version="0.0.1", +) as client: + entities = list(load_dryrun_entities("dryrun.json")) + client.ingest(entities=entities) +``` + +### Dry run mode + +`DiodeDryRunClient` allows generating ingestion requests without contacting a +Diode server. Each request is printed to stdout or written to a JSON Lines file +when `dry_run_output_file` (or `DIODE_DRY_RUN_OUTPUT_FILE`) is set. + +```python +from netboxlabs.diode.sdk import DiodeDryRunClient + with DiodeDryRunClient(dry_run_output_file="dryrun.jsonl") as client: client.ingest([ Entity(device="Device A"), diff --git a/netboxlabs/diode/sdk/client.py b/netboxlabs/diode/sdk/client.py index ee772cc..8734850 100644 --- a/netboxlabs/diode/sdk/client.py +++ b/netboxlabs/diode/sdk/client.py @@ -18,7 +18,7 @@ import certifi import grpc import sentry_sdk -from google.protobuf.json_format import MessageToDict, ParseDict +from google.protobuf.json_format import MessageToJson, ParseDict from netboxlabs.diode.sdk.diode.v1 import ingester_pb2, ingester_pb2_grpc from netboxlabs.diode.sdk.exceptions import DiodeClientError, DiodeConfigError @@ -37,14 +37,25 @@ def load_dryrun_entities(file_path: str | Path) -> Iterable[Entity]: - """Yield entities stored in a JSON Lines file produced by ``DiodeDryRunClient``.""" - with open(file_path) as fh: - for line in fh: - data = json.loads(line) - for entity_dict in data.get("entities", []): - pb_entity = Entity() - ParseDict(entity_dict, pb_entity) - yield pb_entity + """Yield entities from a file with concatenated JSON messages.""" + file_path = Path(file_path) + with file_path.open("r") as fh: + buffer = fh.read() + decoder = json.JSONDecoder() + idx = 0 + buffer = buffer.lstrip() # Remove leading whitespace + while idx < len(buffer): + try: + obj, offset = decoder.raw_decode(buffer[idx:]) + idx += offset + while idx < len(buffer) and buffer[idx].isspace(): + idx += 1 # skip whitespace between JSON objects + for entity_dict in obj.get("entities", []): + entity_pb = ingester_pb2.Entity() + ParseDict(entity_dict, entity_pb) + yield entity_pb + except json.JSONDecodeError as e: + raise RuntimeError(f"Failed to decode JSON object at pos {idx}: {e}") class DiodeClientInterface: @@ -358,7 +369,7 @@ def ingest( sdk_version=self.version, ) - output = json.dumps(MessageToDict(request)) + output = MessageToJson(request, preserving_proto_field_name=True) if self._dry_run_output_file: with open(self._dry_run_output_file, "a") as fh: fh.write(output + "\n") From 0dbb0a4c4f62db7dfefd2da7c068ddf4c9751751 Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Thu, 12 Jun 2025 13:49:00 -0300 Subject: [PATCH 10/18] correct readme --- README.md | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/README.md b/README.md index f783215..d6734e1 100644 --- a/README.md +++ b/README.md @@ -106,35 +106,6 @@ with DiodeClient( client.ingest(entities=entities) ``` -### Dry run mode - -`DiodeDryRunClient` allows generating ingestion requests without contacting a -Diode server. Each request is printed to stdout or written to a JSON Lines file -when `dry_run_output_file` (or `DIODE_DRY_RUN_OUTPUT_FILE`) is set. - -```python -from netboxlabs.diode.sdk import DiodeDryRunClient - -with DiodeDryRunClient(dry_run_output_file="dryrun.jsonl") as client: - client.ingest([ - Entity(device="Device A"), - ]) -``` - -The produced file can later be ingested by a real Diode instance using -`load_dryrun_entities` with a standard `DiodeClient`: - -```python -from netboxlabs.diode.sdk import DiodeClient, load_dryrun_entities - -with DiodeClient( - target="grpc://localhost:8080/diode", - app_name="my-test-app", - app_version="0.0.1", -) as client: - client.ingest(entities=load_dryrun_entities("dryrun.jsonl")) -``` - ## Supported entities (object types) * ASN From a22df50df94f9c026b336c248983cde3b95ce1fa Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Thu, 12 Jun 2025 16:18:22 -0300 Subject: [PATCH 11/18] Fix json file --- netboxlabs/diode/sdk/client.py | 44 ++++++++++++++++++---------------- tests/test_client.py | 2 +- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/netboxlabs/diode/sdk/client.py b/netboxlabs/diode/sdk/client.py index 8734850..cb3d139 100644 --- a/netboxlabs/diode/sdk/client.py +++ b/netboxlabs/diode/sdk/client.py @@ -38,25 +38,13 @@ def load_dryrun_entities(file_path: str | Path) -> Iterable[Entity]: """Yield entities from a file with concatenated JSON messages.""" - file_path = Path(file_path) - with file_path.open("r") as fh: - buffer = fh.read() - decoder = json.JSONDecoder() - idx = 0 - buffer = buffer.lstrip() # Remove leading whitespace - while idx < len(buffer): - try: - obj, offset = decoder.raw_decode(buffer[idx:]) - idx += offset - while idx < len(buffer) and buffer[idx].isspace(): - idx += 1 # skip whitespace between JSON objects - for entity_dict in obj.get("entities", []): - entity_pb = ingester_pb2.Entity() - ParseDict(entity_dict, entity_pb) - yield entity_pb - except json.JSONDecodeError as e: - raise RuntimeError(f"Failed to decode JSON object at pos {idx}: {e}") - + path = Path(file_path) + with path.open("r") as fh: + requests = json.load(fh) + for req_dict in requests: + req_pb = ingester_pb2.IngestRequest() + ParseDict(req_dict, req_pb) + yield from req_pb.entities class DiodeClientInterface: """Runtime placeholder for the Diode client interface.""" @@ -371,8 +359,22 @@ def ingest( output = MessageToJson(request, preserving_proto_field_name=True) if self._dry_run_output_file: - with open(self._dry_run_output_file, "a") as fh: - fh.write(output + "\n") + path = Path(self._dry_run_output_file) + if not path.exists(): + with path.open("w") as fh: + fh.write("[\n") + fh.write(output) + fh.write("\n]") + return ingester_pb2.IngestResponse() + with path.open("rb+") as fh: + fh.seek(-2, os.SEEK_END) + trailer = fh.read(2) + if trailer != b"\n]": + return ingester_pb2.IngestResponse( + errors=["Invalid JSON trailer in dry run output file"] + ) + fh.seek(-2, os.SEEK_END) + fh.write(f",\n{output}\n]".encode()) else: print(output, file=sys.stdout) return ingester_pb2.IngestResponse() diff --git a/tests/test_client.py b/tests/test_client.py index 39aefa2..4dc7c81 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -690,7 +690,7 @@ def test_ingest_dry_run_file(tmp_path): client.ingest(entities=[]) assert client._stub.Ingest.call_count == 0 - assert output_file.read_text().startswith("{") + assert output_file.read_text().startswith("[") def test_load_dryrun_entities(tmp_path): From 2b6721a2c3ecd3e82f13affbc79939bad38dde9f Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Fri, 13 Jun 2025 10:13:16 -0300 Subject: [PATCH 12/18] add fixtures --- tests/fixtures/messages.json | 3810 ++++++++++++++++++++++++++++++++++ 1 file changed, 3810 insertions(+) create mode 100644 tests/fixtures/messages.json diff --git a/tests/fixtures/messages.json b/tests/fixtures/messages.json new file mode 100644 index 0000000..7fd4738 --- /dev/null +++ b/tests/fixtures/messages.json @@ -0,0 +1,3810 @@ +[ + { + "stream": "latest", + "entities": [ + { + "timestamp": "2025-06-13T13:04:56.416909Z", + "asn": { + "asn": "555", + "rir": { + "name": "RIR 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "description": "ASN 555 Description", + "comments": "ASN 555 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:56.416909Z", + "asn_range": { + "name": "ASN Range 1", + "slug": "asn-range-1", + "rir": { + "name": "RIR 1" + }, + "start": "1", + "end": "2", + "tenant": { + "name": "Tenant 1" + }, + "description": "ASN Range 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:56.416909Z", + "aggregate": { + "prefix": "182.82.82.0/24", + "rir": { + "name": "RIR 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "date_added": "2025-04-14T08:08:55Z", + "description": "Aggregate Description", + "comments": "Aggregate Comments", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:56.416909Z", + "circuit": { + "cid": "Circuit 1", + "provider": { + "name": "Provider 1" + }, + "provider_account": { + "provider": { + "name": "Provider 1" + }, + "account": "account1" + }, + "type": { + "name": "Circuit Type 1" + }, + "status": "offline", + "tenant": { + "name": "Tenant 1" + }, + "install_date": "2025-04-14T00:00:00Z", + "termination_date": "2025-04-14T00:00:00Z", + "commit_rate": "10", + "description": "Circuit 1 Description", + "distance": 12.4, + "distance_unit": "ft", + "comments": "Circuit 1 Comments", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:56.416909Z", + "circuit_group": { + "name": "Circuit Group 1", + "description": "Circuit Group 1 Description", + "tenant": { + "name": "Tenant 1" + }, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:56.416909Z", + "circuit_group_assignment": { + "group": { + "name": "Circuit Group 1" + }, + "member_circuit": { + "cid": "Circuit 1", + "type": { + "name": "Circuit Type 1" + }, + "provider": { + "name": "Provider 1" + } + }, + "priority": "tertiary" + } + }, + { + "timestamp": "2025-06-13T13:04:56.416909Z", + "circuit_group_assignment": { + "group": { + "name": "Circuit Group 1" + }, + "member_virtual_circuit": { + "cid": "Virtual Circuit 1", + "type": { + "name": "Virtual Circuit Type 1" + }, + "provider_network": { + "name": "Provider Network 1", + "provider": { + "name": "Provider 1" + } + } + }, + "priority": "tertiary" + } + }, + { + "timestamp": "2025-06-13T13:04:56.416909Z", + "circuit_termination": { + "circuit": { + "cid": "Circuit 1", + "type": { + "name": "Circuit Type 1" + }, + "provider": { + "name": "Provider 1" + } + }, + "term_side": "A", + "termination_location": { + "name": "attic", + "site": { + "name": "Site 1" + } + }, + "port_speed": "9600", + "upstream_speed": "14400", + "xconnect_id": "xconnect.1", + "pp_info": "pp info", + "description": "description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:56.416909Z", + "circuit_termination": { + "circuit": { + "cid": "Circuit 1", + "type": { + "name": "Circuit Type 1" + }, + "provider": { + "name": "Provider 1" + } + }, + "term_side": "A", + "termination_provider_network": { + "provider": { + "name": "Provider 1" + }, + "name": "Provider Network 1", + "service_id": "service.1" + }, + "port_speed": "9600", + "upstream_speed": "14400", + "xconnect_id": "xconnect.1", + "pp_info": "pp info", + "description": "description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:56.416909Z", + "circuit_termination": { + "circuit": { + "cid": "Circuit 1", + "type": { + "name": "Circuit Type 1" + }, + "provider": { + "name": "Provider 1" + } + }, + "term_side": "A", + "termination_site": { + "name": "Site 1" + }, + "port_speed": "9600", + "upstream_speed": "14400", + "xconnect_id": "xconnect.1", + "pp_info": "pp info", + "description": "description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + } + ], + "id": "ae9c981f-685c-4fbc-b9ce-b5fa00135b8c", + "sdk_name": "diode-sdk-python-dry-run", + "sdk_version": "0.0.0" + }, + { + "stream": "latest", + "entities": [ + { + "timestamp": "2025-06-13T13:04:57.416909Z", + "circuit_termination": { + "circuit": { + "cid": "Circuit 1", + "type": { + "name": "Circuit Type 1" + }, + "provider": { + "name": "Provider 1" + } + }, + "term_side": "A", + "termination_site_group": { + "name": "Site Group 1" + }, + "port_speed": "9600", + "upstream_speed": "14400", + "xconnect_id": "xconnect.1", + "pp_info": "pp info", + "description": "description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:57.416909Z", + "circuit_type": { + "name": "Circuit Type 1", + "slug": "circuit-type-1", + "color": "0000ff", + "description": "Circuit Type 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:57.416909Z", + "cluster": { + "name": "Cluster A", + "type": { + "name": "Cluster Type 1" + }, + "group": { + "name": "Cluster Group 1" + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "scope_location": { + "name": "Location 1", + "site": { + "name": "Site 1" + } + }, + "description": "Cluster 1 Description", + "comments": "Cluster 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:57.416909Z", + "cluster": { + "name": "Cluster 2", + "type": { + "name": "Cluster Type 1" + }, + "group": { + "name": "Cluster Group 1" + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "scope_region": { + "name": "Region 1" + }, + "description": "Cluster 1 Description", + "comments": "Cluster 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:57.416909Z", + "cluster": { + "name": "Cluster 3", + "type": { + "name": "Cluster Type 1" + }, + "group": { + "name": "Cluster Group 1" + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "scope_site": { + "name": "Site 1" + }, + "description": "Cluster 1 Description", + "comments": "Cluster 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:57.416909Z", + "cluster": { + "name": "Cluster 4", + "type": { + "name": "Cluster Type 1" + }, + "group": { + "name": "Cluster Group 1" + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "scope_site_group": { + "name": "Site Group 1" + }, + "description": "Cluster 1 Description", + "comments": "Cluster 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:57.416909Z", + "cluster_group": { + "name": "Cluster Group 1", + "description": "Cluster Group 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:57.416909Z", + "cluster_type": { + "name": "Cluster Type 1", + "description": "Cluster Type 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:57.416909Z", + "console_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Manufacturer 1" + }, + "model": "Module Type 1" + } + }, + "name": "Console Port 1", + "label": "Console Port 1 Label", + "type": "db-25", + "speed": "1200", + "description": "Console Port 1 Description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:57.416909Z", + "console_server_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Manufacturer 1" + }, + "model": "Module Type 1" + } + }, + "name": "Console Server Port 1", + "label": "Console Server Port 1 Label", + "type": "db-25", + "speed": "1200", + "description": "Console Server Port 1 Description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + } + ], + "id": "029704fa-d34d-4d8b-a8e0-87ccdd3cb811", + "sdk_name": "diode-sdk-python-dry-run", + "sdk_version": "0.0.0" + }, + { + "stream": "latest", + "entities": [ + { + "timestamp": "2025-06-13T13:04:58.416909Z", + "contact": { + "group": { + "name": "Contact Group 1" + }, + "name": "Contact 1", + "title": "Contact 1 Title", + "phone": "1234567890", + "email": "contact1@example.com", + "address": "1234 Main St, Anytown, USA", + "link": "https://example.com", + "description": "Contact 1 Description", + "comments": "Contact 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:58.416909Z", + "contact_assignment": { + "contact": { + "name": "Contact 1" + }, + "role": { + "name": "Contact Role 1" + }, + "priority": "primary", + "tags": [ + { + "name": "Tag 1" + } + ], + "object_site": { + "name": "Site 1" + } + } + }, + { + "timestamp": "2025-06-13T13:04:58.416909Z", + "contact_group": { + "name": "Contact Group 1", + "parent": { + "name": "Contact Group 2" + }, + "description": "Contact Group 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:58.416909Z", + "contact_role": { + "name": "Contact Role 1", + "description": "Contact Role 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:58.416909Z", + "device": { + "name": "Device ABC", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "platform": { + "name": "Platform 1" + }, + "serial": "1234567890", + "asset_tag": "asset.1", + "site": { + "name": "Site 1" + }, + "location": { + "name": "Location 1", + "site": { + "name": "Site 1" + } + }, + "rack": { + "name": "Rack 1", + "site": { + "name": "Site 1" + }, + "location": { + "name": "Location 1", + "site": { + "name": "Site 1" + } + } + }, + "position": 1.0, + "face": "front", + "latitude": 34.0, + "longitude": 75.0, + "status": "active", + "airflow": "bottom-to-top", + "primary_ip4": { + "address": "192.168.99.1", + "assigned_object_interface": { + "name": "GigabitEthernet1/0/1", + "type": "1000base-t", + "device": { + "name": "Device ABC", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "site": { + "name": "Site 1" + } + } + } + }, + "primary_ip6": { + "address": "2001:ddd::1", + "assigned_object_interface": { + "name": "GigabitEthernet1/0/1", + "type": "1000base-t", + "device": { + "name": "Device ABC", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "site": { + "name": "Site 1" + } + } + } + }, + "cluster": { + "name": "Cluster 1", + "type": { + "name": "Cluster Type 1" + } + }, + "virtual_chassis": { + "name": "Virtual Chassis 1" + }, + "vc_position": "1", + "vc_priority": "1", + "description": "Device 1 Description", + "comments": "Device 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:58.416909Z", + "device_bay": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C3P0", + "subdevice_role": "parent" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Device Bay 1", + "label": "Device Bay 1 Label", + "description": "Device Bay 1 Description", + "installed_device": { + "name": "Device 2", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:58.416909Z", + "device_role": { + "name": "Core Router", + "slug": "core-router", + "color": "ff0000", + "vm_role": true, + "description": "Primary network routing device", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:58.416909Z", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "default_platform": { + "name": "IOS-XE" + }, + "model": "Catalyst 9300", + "slug": "catalyst-9300", + "part_number": "C9300-48P-E", + "u_height": 1.0, + "exclude_from_utilization": false, + "is_full_depth": true, + "subdevice_role": "parent", + "airflow": "front-to-rear", + "weight": 14.5, + "weight_unit": "lb", + "description": "Enterprise Series Switch", + "comments": "High-performance access switch", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:58.416909Z", + "fhrp_group": { + "name": "HSRP Group 10", + "protocol": "hsrp", + "group_id": "10", + "auth_type": "md5", + "auth_key": "secretkey123", + "description": "Core Router HSRP Group", + "comments": "Primary gateway redundancy group", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:58.416909Z", + "fhrp_group_assignment": { + "group": { + "name": "HSRP Group 10", + "protocol": "hsrp", + "group_id": "10" + }, + "interface_interface": { + "device": { + "name": "Device 1", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "site": { + "name": "Site 1" + } + }, + "name": "GigabitEthernet1/0/1", + "type": "1000base-t", + "enabled": true + }, + "priority": "100" + } + } + ], + "id": "6cbad6f7-e950-40c8-b6cb-4f1603629dd8", + "sdk_name": "diode-sdk-python-dry-run", + "sdk_version": "0.0.0" + }, + { + "stream": "latest", + "entities": [ + { + "timestamp": "2025-06-13T13:04:59.416909Z", + "front_port": { + "device": { + "name": "Device 1", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-MODULE" + } + }, + "name": "Front Port 1", + "label": "FP1", + "type": "lc-apc", + "color": "0000ff", + "rear_port": { + "device": { + "name": "Device 1", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Rear Port 1", + "type": "lc-apc" + }, + "rear_port_position": "1", + "description": "Front fiber port", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:59.416909Z", + "ike_policy": { + "name": "IKE-POLICY-1", + "description": "Main IPSec IKE Policy", + "version": "2", + "preshared_key": "secretPSK123!", + "comments": "Primary IKE policy for VPN tunnels", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "proposals": [ + { + "name": "IKE-PROPOSAL-1", + "description": "AES-256 with SHA-256", + "authentication_method": "preshared-keys", + "encryption_algorithm": "aes-256-cbc", + "authentication_algorithm": "hmac-sha256", + "group": "14", + "sa_lifetime": "28800" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:59.416909Z", + "ike_proposal": { + "name": "IKE-PROPOSAL-2", + "description": "High Security IKE Proposal", + "authentication_method": "certificates", + "encryption_algorithm": "aes-256-gcm", + "authentication_algorithm": "hmac-sha512", + "group": "21", + "sa_lifetime": "86400", + "comments": "Enhanced security proposal for critical VPNs", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:59.416909Z", + "ip_address": { + "address": "192.168.100.1/24", + "vrf": { + "name": "PROD-VRF", + "rd": "65000:1" + }, + "tenant": { + "name": "Tenant 1" + }, + "status": "active", + "role": "vip", + "assigned_object_interface": { + "device": { + "name": "Device 1", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "site": { + "name": "Site 1" + } + }, + "name": "GigabitEthernet1/0/1", + "type": "1000base-t" + }, + "nat_inside": { + "address": "10.0.0.1/24" + }, + "dns_name": "prod-vip.example.com", + "description": "Production VIP Address", + "comments": "Primary virtual IP for load balancing", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:59.416909Z", + "ip_range": { + "start_address": "10.100.0.1", + "end_address": "10.100.0.254", + "vrf": { + "name": "PROD-VRF", + "rd": "65000:1" + }, + "tenant": { + "name": "Tenant 1" + }, + "status": "active", + "role": { + "name": "Server Pool", + "slug": "server-pool" + }, + "description": "Production Server IP Range", + "comments": "Allocated for production server deployments", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "mark_utilized": true + } + }, + { + "timestamp": "2025-06-13T13:04:59.416909Z", + "ip_sec_policy": { + "name": "IPSEC-POLICY-1", + "description": "Site-to-Site VPN Policy", + "pfs_group": "14", + "comments": "High-security IPSec policy for site-to-site VPN", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "proposals": [ + { + "name": "IPSEC-PROPOSAL-1", + "description": "AES-256-GCM with ESP", + "encryption_algorithm": "aes-256-gcm", + "sa_lifetime_seconds": "28800", + "sa_lifetime_data": "28800", + "comments": "Strong encryption proposal for VPN tunnels" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:59.416909Z", + "ip_sec_profile": { + "name": "IPSEC-PROFILE-1", + "description": "Remote Access VPN Profile", + "mode": "esp", + "ike_policy": { + "name": "IKE-POLICY-1", + "version": "2", + "preshared_key": "secretkey123" + }, + "ipsec_policy": { + "name": "IPSEC-POLICY-1", + "description": "Strong encryption policy", + "pfs_group": "14" + }, + "comments": "Standard IPSec profile for remote access VPN tunnels", + "tags": [ + { + "name": "VPN" + }, + { + "name": "Remote-Access" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:59.416909Z", + "ip_sec_proposal": { + "name": "IPSec-Proposal-AES256", + "description": "High security IPSec proposal using AES-256-GCM", + "encryption_algorithm": "aes-256-gcm", + "authentication_algorithm": "hmac-sha512", + "sa_lifetime_seconds": "28800", + "sa_lifetime_data": "42949", + "comments": "Used for critical infrastructure VPNs", + "tags": [ + { + "name": "high-security", + "slug": "high-security", + "color": "0000ff" + }, + { + "name": "production", + "slug": "production", + "color": "0000ff" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:59.416909Z", + "interface": { + "name": "GigabitEthernet1/0/1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-MODULE" + } + }, + "label": "Core Link 1", + "type": "1000base-t", + "enabled": true, + "bridge": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Bridge1", + "type": "bridge" + }, + "lag": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Port-Channel2", + "type": "lag" + }, + "mtu": "9000", + "primary_mac_address": { + "mac_address": "00:11:22:33:44:55" + }, + "speed": "1000000000", + "duplex": "full", + "wwn": "50:01:43:80:00:00:00:00", + "vrf": { + "name": "PROD-VRF", + "rd": "65000:1" + }, + "description": "Core network interface", + "mode": "tagged", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "mgmt_only": false, + "poe_mode": "pse", + "poe_type": "type3-ieee802.3bt", + "untagged_vlan": { + "vid": 100, + "name": "Data VLAN", + "status": "active" + }, + "vlan_translation_policy": { + "name": "Customer Translation Policy", + "description": "VLAN translation for customer traffic" + }, + "vdcs": [ + { + "name": "VDC1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "identifier": 1, + "status": "active", + "description": "Primary VDC" + } + ], + "tagged_vlans": [ + { + "vid": 101, + "name": "Voice VLAN", + "status": "active" + }, + { + "vid": 102, + "name": "Data VLAN", + "status": "active" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:04:59.416909Z", + "interface": { + "name": "WirelessGigabitEthernet1/0/1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-MODULE" + } + }, + "label": "Core Link 1", + "type": "other-wireless", + "enabled": true, + "bridge": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Bridge1", + "type": "bridge" + }, + "lag": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Port-Channel2", + "type": "lag" + }, + "mtu": "9000", + "primary_mac_address": { + "mac_address": "00:11:22:33:44:55" + }, + "speed": "1000000000", + "duplex": "full", + "wwn": "50:01:43:80:00:00:00:00", + "rf_role": "ap", + "rf_channel": "2.4g-1-2412-22", + "tx_power": "20", + "wireless_lans": [ + { + "ssid": "Corp-Secure", + "description": "Corporate secure wireless network", + "group": { + "name": "Corporate Networks", + "slug": "corporate-networks" + }, + "status": "active", + "vlan": { + "vid": 800, + "name": "Production Servers" + }, + "tenant": { + "name": "Tenant 1" + } + } + ], + "vrf": { + "name": "PROD-VRF" + }, + "description": "Core network interface", + "mode": "access", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "mgmt_only": false, + "untagged_vlan": { + "vid": 900, + "name": "Data VLAN", + "status": "active" + }, + "vlan_translation_policy": { + "name": "Customer Translation Policy", + "description": "VLAN translation for customer traffic" + }, + "vdcs": [ + { + "name": "VDC1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "identifier": 1, + "status": "active", + "description": "Primary VDC" + } + ], + "tagged_vlans": [ + { + "vid": 101, + "name": "Voice VLAN", + "status": "active" + }, + { + "vid": 102, + "name": "Data VLAN", + "status": "active" + } + ] + } + } + ], + "id": "67cc662a-4598-4fb2-a39c-788344fb0e55", + "sdk_name": "diode-sdk-python-dry-run", + "sdk_version": "0.0.0" + }, + { + "stream": "latest", + "entities": [ + { + "timestamp": "2025-06-13T13:05:00.416909Z", + "interface": { + "name": "VirtualGigabitEthernet1/0/1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "parent": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Port-Channel1", + "type": "1000base-t" + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-MODULE" + } + }, + "label": "Core Link 1", + "type": "virtual", + "enabled": true, + "bridge": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Bridge1", + "type": "bridge" + }, + "mtu": "9000", + "primary_mac_address": { + "mac_address": "00:11:22:33:44:55" + }, + "speed": "1000000000", + "duplex": "full", + "wwn": "50:01:43:80:00:00:00:00", + "vrf": { + "name": "PROD-VRF" + }, + "description": "Core network interface", + "mode": "q-in-q", + "mark_connected": false, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "mgmt_only": false, + "untagged_vlan": { + "vid": 444, + "name": "Data VLAN", + "status": "active" + }, + "qinq_svlan": { + "vid": 2000, + "name": "Service VLAN", + "status": "active" + }, + "vlan_translation_policy": { + "name": "Customer Translation Policy", + "description": "VLAN translation for customer traffic" + }, + "vdcs": [ + { + "name": "VDC1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "identifier": 1, + "status": "active", + "description": "Primary VDC" + } + ], + "tagged_vlans": [ + { + "vid": 101, + "name": "Voice VLAN", + "status": "active" + }, + { + "vid": 102, + "name": "Data VLAN", + "status": "active" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:00.416909Z", + "inventory_item": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "parent": { + "name": "Chassis 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "name": "Power Supply 1", + "label": "PSU1", + "role": { + "name": "Power Supply", + "color": "00ff00" + }, + "manufacturer": { + "name": "Cisco" + }, + "part_id": "PWR-C1-715WAC", + "serial": "ABC123XYZ", + "asset_tag": "ASSET-001", + "discovered": true, + "description": "715W AC Power Supply", + "status": "active", + "component_power_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "PSU1 Power Port", + "type": "iec-60320-c14", + "maximum_draw": 715, + "allocated_draw": 500, + "description": "Power input port for PSU1" + }, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:00.416909Z", + "inventory_item_role": { + "name": "Line Card", + "slug": "line-card", + "color": "0000ff", + "description": "Network switch line card module", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:00.416909Z", + "l2vpn": { + "name": "Customer-VPLS-1", + "slug": "customer-vpls-1", + "type": "vpls", + "identifier": "65000", + "import_targets": [ + { + "name": "65000:1001", + "description": "Primary import target" + }, + { + "name": "65000:1002", + "description": "Secondary import target" + } + ], + "export_targets": [ + { + "name": "65000:1003", + "description": "Primary export target" + } + ], + "description": "Customer VPLS service for multi-site connectivity", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:00.416909Z", + "l2vpn_termination": { + "l2vpn": { + "name": "Customer-VPLS-1", + "type": "vpls", + "identifier": "65000" + }, + "assigned_object_interface": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "GigabitEthernet1/0/1", + "type": "1000base-t", + "enabled": true + }, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:00.416909Z", + "location": { + "name": "Data Center East Wing", + "slug": "dc-east-wing", + "site": { + "name": "Site 1" + }, + "parent": { + "name": "Main Data Center", + "slug": "main-dc", + "site": { + "name": "Site 1" + } + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "facility": "Building A, Floor 3", + "description": "East wing of the main data center facility", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:00.416909Z", + "mac_address": { + "mac_address": "00:1A:2B:3C:4D:5E", + "assigned_object_interface": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "GigabitEthernet1/0/1", + "type": "1000base-t", + "enabled": true + }, + "description": "Primary management interface MAC", + "comments": "Reserved for network management access", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:00.416909Z", + "manufacturer": { + "name": "Arista Networks", + "slug": "arista-networks", + "description": "Leading provider of cloud networking solutions", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:00.416909Z", + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-STACK" + }, + "status": "active", + "serial": "MOD123XYZ", + "asset_tag": "MOD-001", + "description": "Stacking module for switch interconnect", + "comments": "Primary stack member module", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:00.416909Z", + "module_bay": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Stack Module Bay 2", + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-STACK" + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + } + }, + "label": "STACK-2", + "position": "Rear", + "description": "Secondary stacking module bay", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + } + ], + "id": "5a0eb383-c2b5-439b-be75-444c547a3d9e", + "sdk_name": "diode-sdk-python-dry-run", + "sdk_version": "0.0.0" + }, + { + "stream": "latest", + "entities": [ + { + "timestamp": "2025-06-13T13:05:01.416909Z", + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C9300-NM-8X", + "part_number": "C9300-NM-8X=", + "airflow": "front-to-rear", + "weight": 0.7, + "weight_unit": "kg", + "description": "Catalyst 9300 8 x 10GE Network Module", + "comments": "Hot-swappable uplink module for C9300 series switches", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:01.416909Z", + "platform": { + "name": "Cisco IOS-XE", + "slug": "cisco-ios-xe", + "manufacturer": { + "name": "Cisco" + }, + "description": "Enterprise-class IOS operating system for Catalyst switches and ISR routers", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:01.416909Z", + "power_feed": { + "power_panel": { + "site": { + "name": "Site 1" + }, + "name": "Panel A" + }, + "rack": { + "name": "Rack 1", + "site": { + "name": "Site 1" + } + }, + "name": "Power Feed A1", + "status": "active", + "type": "primary", + "supply": "ac", + "phase": "three-phase", + "voltage": "208", + "amperage": "30", + "max_utilization": "80", + "mark_connected": true, + "description": "Primary power feed for network equipment rack", + "tenant": { + "name": "Tenant 1" + }, + "comments": "Connected to UPS system A with redundant backup", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:01.416909Z", + "power_outlet": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "PWR-C1-715WAC" + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + } + }, + "name": "PSU1-Outlet1", + "label": "OUT-1", + "type": "iec-60320-c13", + "color": "0000ff", + "power_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "PSU1" + }, + "feed_leg": "A", + "description": "Power outlet for network switch PSU", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:01.416909Z", + "power_panel": { + "site": { + "name": "Site 1" + }, + "location": { + "name": "Data Center East Wing", + "slug": "dc-east-wing", + "site": { + "name": "Site 1" + } + }, + "name": "Panel B", + "description": "Secondary power distribution panel for network equipment", + "comments": "Connected to redundant UPS system with automatic transfer switch", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:01.416909Z", + "power_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "PWR-C1-715WAC" + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + } + }, + "name": "PSU2", + "label": "PWR-2", + "type": "iec-60320-c14", + "maximum_draw": "715", + "allocated_draw": "650", + "description": "Secondary power supply unit input", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:01.416909Z", + "prefix": { + "prefix": "10.100.0.0/16", + "vrf": { + "name": "PROD-VRF", + "rd": "65000:1" + }, + "scope_site": { + "name": "Site 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "vlan": { + "name": "Production VLAN", + "vid": "112" + }, + "status": "active", + "role": { + "name": "Production", + "slug": "production" + }, + "is_pool": true, + "mark_utilized": true, + "description": "Production network address space", + "comments": "Primary address allocation for production services", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:01.416909Z", + "provider": { + "name": "Level 3 Communications", + "slug": "level3", + "description": "Global Tier 1 Internet Service Provider", + "comments": "Primary transit provider for data center connectivity", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "accounts": [ + { + "provider": { + "name": "Level 3 Communications" + }, + "name": "East Coast Account", + "account": "L3-12345", + "description": "East Coast regional services account", + "comments": "Managed through regional NOC" + }, + { + "provider": { + "name": "Level 3 Communications" + }, + "name": "West Coast Account", + "account": "L3-67890", + "description": "West Coast regional services account", + "comments": "Managed through regional NOC" + } + ], + "asns": [ + { + "asn": "3356", + "rir": { + "name": "ARIN" + }, + "tenant": { + "name": "Tenant 1" + }, + "description": "Level 3 Global ASN", + "comments": "Primary transit ASN" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:01.416909Z", + "provider_account": { + "provider": { + "name": "AT&T" + }, + "name": "Global Enterprise Services", + "account": "ATT-GES-123456", + "description": "Global enterprise services and solutions account", + "comments": "Primary account for worldwide MPLS and managed services", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:01.416909Z", + "provider_network": { + "provider": { + "name": "Level 3 Communications" + }, + "name": "Global MPLS Network", + "service_id": "L3-MPLS-001", + "description": "Global MPLS backbone network", + "comments": "Primary enterprise MPLS network infrastructure", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + } + ], + "id": "479f1a4c-9503-448c-a9f8-63d759b5ad0b", + "sdk_name": "diode-sdk-python-dry-run", + "sdk_version": "0.0.0" + }, + { + "stream": "latest", + "entities": [ + { + "timestamp": "2025-06-13T13:05:02.416909Z", + "rir": { + "name": "ARIN", + "slug": "arin", + "is_private": false, + "description": "American Registry for Internet Numbers", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:02.416909Z", + "rack": { + "name": "Rack 1", + "facility_id": "FAC-001", + "site": { + "name": "Site 1" + }, + "location": { + "name": "Data Center East Wing", + "site": { + "name": "Site 1" + } + }, + "tenant": { + "name": "Tenant 1" + }, + "status": "active", + "role": { + "name": "Server Rack", + "slug": "server-rack", + "color": "0000ff", + "description": "Primary server rack role" + }, + "serial": "RACK123XYZ", + "asset_tag": "RACK-001", + "rack_type": { + "manufacturer": { + "name": "Manufacturer 1" + }, + "model": "R2000", + "slug": "r2000", + "form_factor": "4-post-cabinet" + }, + "form_factor": "4-post-cabinet", + "width": "19", + "u_height": "42", + "starting_unit": "1", + "weight": "350.5", + "max_weight": "1000", + "weight_unit": "lb", + "desc_units": false, + "outer_width": "24", + "outer_depth": "36", + "outer_unit": "in", + "mounting_depth": "30", + "airflow": "front-to-rear", + "description": "Standard 42U server rack", + "comments": "Located in primary data center", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:02.416909Z", + "rack_reservation": { + "rack": { + "name": "Rack 1", + "site": { + "name": "Site 1" + } + }, + "units": [ + "1", + "2", + "3", + "4" + ], + "tenant": { + "name": "Tenant 1" + }, + "description": "Reserved for new server deployment", + "comments": "Project XYZ equipment installation", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:02.416909Z", + "rack_role": { + "name": "Network Equipment", + "slug": "network-equipment", + "color": "0000ff", + "description": "Dedicated racks for network infrastructure", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:02.416909Z", + "rack_type": { + "manufacturer": { + "name": "Manufacturer 1" + }, + "model": "R2000", + "slug": "r2000", + "description": "Standard 42U server rack", + "form_factor": "4-post-cabinet", + "width": "19", + "u_height": "42", + "starting_unit": "1", + "desc_units": false, + "outer_width": "24", + "outer_depth": "36", + "outer_unit": "in", + "weight": 350.5, + "max_weight": "1000", + "weight_unit": "lb", + "mounting_depth": "30", + "comments": "Standard enterprise rack configuration", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:02.416909Z", + "rear_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "asset_tag": "module-1234567890", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-MODULE" + } + }, + "name": "Rear Port 1", + "label": "RP1", + "type": "lc-apc", + "color": "ff00ff", + "positions": "1", + "description": "Rear fiber port", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:02.416909Z", + "region": { + "name": "North America", + "slug": "north-america", + "parent": { + "name": "Global", + "slug": "global", + "description": "Global Region", + "tags": [ + { + "name": "Tag 1" + } + ] + }, + "description": "North American Region", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:02.416909Z", + "role": { + "name": "Network Administrator", + "slug": "network-admin", + "weight": "1000", + "description": "Primary network administration role", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:02.416909Z", + "route_target": { + "name": "65000:3001", + "tenant": { + "name": "Tenant 1" + }, + "description": "Primary route target for MPLS VPN", + "comments": "Used for customer VPN service", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:02.416909Z", + "service": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Web Server", + "protocol": "tcp", + "ports": [ + "80", + "443" + ], + "description": "Primary web server service", + "comments": "Handles HTTPS traffic for main website", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "ipaddresses": [ + { + "address": "192.168.1.100/24", + "status": "active", + "dns_name": "web.example.com" + } + ] + } + } + ], + "id": "ba68d239-8d88-4350-9692-16020ab14b9f", + "sdk_name": "diode-sdk-python-dry-run", + "sdk_version": "0.0.0" + }, + { + "stream": "latest", + "entities": [ + { + "timestamp": "2025-06-13T13:05:03.416909Z", + "site": { + "name": "Data Center West", + "slug": "dc-west", + "status": "active", + "region": { + "name": "North America", + "slug": "north-america" + }, + "group": { + "name": "Primary Data Centers", + "slug": "primary-dcs" + }, + "tenant": { + "name": "Tenant 1" + }, + "facility": "Building 7", + "time_zone": "America/Los_Angeles", + "description": "Primary West Coast Data Center", + "physical_address": "123 Tech Drive, San Jose, CA 95134", + "shipping_address": "Receiving Dock 3, 123 Tech Drive, San Jose, CA 95134", + "latitude": 37.3382, + "longitude": -121.8863, + "comments": "24x7 access requires security clearance", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "asns": [ + { + "asn": "555", + "rir": { + "name": "RIR 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "description": "ASN 555 Description", + "comments": "ASN 555 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:03.416909Z", + "site_group": { + "name": "Global Data Centers", + "slug": "global-dcs", + "parent": { + "name": "Infrastructure", + "slug": "infrastructure" + }, + "description": "Worldwide data center facilities", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:03.416909Z", + "tag": { + "name": "Production", + "slug": "production", + "color": "ff0000" + } + }, + { + "timestamp": "2025-06-13T13:05:03.416909Z", + "tenant": { + "name": "Acme Corporation", + "slug": "acme-corp", + "group": { + "name": "Enterprise Customers", + "slug": "enterprise-customers" + }, + "description": "Global technology solutions provider", + "comments": "Fortune 500 company with worldwide operations", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:03.416909Z", + "tenant_group": { + "name": "Financial Services", + "slug": "financial-services", + "parent": { + "name": "Enterprise Sectors", + "slug": "enterprise-sectors" + }, + "description": "Banking and financial industry customers", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:03.416909Z", + "tunnel": { + "name": "DC-West-to-East-Primary", + "status": "active", + "group": { + "name": "Inter-DC Tunnels", + "slug": "inter-dc-tunnels" + }, + "encapsulation": "ipsec-tunnel", + "ipsec_profile": { + "name": "IPSEC-PROFILE-1", + "mode": "esp", + "ike_policy": { + "name": "IKE-POLICY-TUN-1", + "version": "2", + "preshared_key": "1234567890", + "comments": "Using AES-256-GCM encryption with PFS" + }, + "ipsec_policy": { + "name": "IPSEC-POLICY-1", + "pfs_group": "2" + } + }, + "tenant": { + "name": "Tenant 1" + }, + "tunnel_id": "1001", + "description": "Primary IPSec tunnel between West and East data centers", + "comments": "Using AES-256-GCM encryption with PFS", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:03.416909Z", + "tunnel_group": { + "name": "Regional Backbones", + "slug": "regional-backbones", + "description": "High-capacity encrypted tunnels between regional data centers", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:03.416909Z", + "tunnel_termination": { + "tunnel": { + "name": "DC-West-to-East-Primary", + "status": "active", + "encapsulation": "ipsec-tunnel" + }, + "role": "hub", + "termination_device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "outside_ip": { + "address": "203.0.113.1/24", + "status": "active", + "dns_name": "vpn1.example.com" + }, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:03.416909Z", + "vlan": { + "group": { + "name": "Production VLANs", + "slug": "production-vlans" + }, + "vid": "807", + "name": "Production Servers", + "tenant": { + "name": "Tenant 1" + }, + "status": "active", + "role": { + "name": "Production", + "slug": "production" + }, + "description": "Primary production server network", + "qinq_role": "cvlan", + "qinq_svlan": { + "vid": "1909", + "name": "Service Provider VLAN" + }, + "comments": "Used for customer-facing production workloads", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:03.416909Z", + "vlan_group": { + "name": "Data Center Core", + "slug": "dc-core", + "scope_site": { + "name": "Data Center West", + "slug": "dc-west", + "status": "active" + }, + "description": "Core network VLANs for data center infrastructure", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + } + ], + "id": "287f8602-868b-41d4-92fe-47bb9fc84fbb", + "sdk_name": "diode-sdk-python-dry-run", + "sdk_version": "0.0.0" + }, + { + "stream": "latest", + "entities": [ + { + "timestamp": "2025-06-13T13:05:04.416909Z", + "vlan_translation_policy": { + "name": "Customer Edge Translation", + "description": "VLAN translation policy for customer edge interfaces" + } + }, + { + "timestamp": "2025-06-13T13:05:04.416909Z", + "vlan_translation_rule": { + "policy": { + "name": "Customer Edge Translation", + "description": "VLAN translation policy for customer edge interfaces" + }, + "local_vid": "100", + "remote_vid": "1100", + "description": "Map customer VLAN 100 to provider VLAN 1100" + } + }, + { + "timestamp": "2025-06-13T13:05:04.416909Z", + "vm_interface": { + "virtual_machine": { + "name": "web-server-01", + "status": "active", + "role": { + "name": "Web Server" + }, + "site": { + "name": "Site 1" + } + }, + "name": "eth0", + "enabled": true, + "parent": { + "virtual_machine": { + "name": "web-server-01", + "status": "active", + "role": { + "name": "Web Server" + }, + "site": { + "name": "Site 1" + } + }, + "name": "bond0" + }, + "bridge": { + "virtual_machine": { + "name": "web-server-01", + "status": "active", + "role": { + "name": "Web Server" + }, + "site": { + "name": "Site 1" + } + }, + "name": "br0" + }, + "mtu": "9000", + "primary_mac_address": { + "mac_address": "00:1A:2B:3C:4D:5E" + }, + "description": "Primary network interface", + "mode": "q-in-q", + "untagged_vlan": { + "vid": "1101", + "name": "Production Servers" + }, + "qinq_svlan": { + "vid": "1000", + "name": "Service Provider VLAN" + }, + "vlan_translation_policy": { + "name": "Customer Edge Translation" + }, + "vrf": { + "name": "PROD-VRF", + "rd": "65000:1" + }, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:04.416909Z", + "vrf": { + "name": "Customer-A-VRF", + "rd": "65000:100", + "tenant": { + "name": "Tenant 1" + }, + "enforce_unique": true, + "description": "Isolated routing domain for Customer A", + "comments": "Used for customer's private network services", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "import_targets": [ + { + "name": "65000:100" + }, + { + "name": "65000:101" + } + ], + "export_targets": [ + { + "name": "65000:103" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:04.416909Z", + "virtual_chassis": { + "name": "Stack-DC1-Core", + "domain": "dc1-core.example.com", + "master": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "description": "Core switch stack in DC1", + "comments": "Primary switching infrastructure for data center 1", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:04.416909Z", + "virtual_circuit": { + "cid": "VC-001-LAX-NYC", + "provider_network": { + "provider": { + "name": "Level 3 Communications" + }, + "name": "Global MPLS Network", + "service_id": "L3-MPLS-001" + }, + "provider_account": { + "provider": { + "name": "Level 3 Communications" + }, + "name": "East Coast Account", + "account": "L3-12345" + }, + "type": { + "name": "MPLS L3VPN", + "slug": "mpls-l3vpn" + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "description": "LAX to NYC MPLS circuit", + "comments": "Primary east-west connectivity", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:04.416909Z", + "virtual_circuit_termination": { + "virtual_circuit": { + "cid": "VC-001-LAX-NYC", + "provider_network": { + "provider": { + "name": "Level 3 Communications" + }, + "name": "Global MPLS Network" + }, + "type": { + "name": "MPLS L3VPN", + "slug": "mpls-l3vpn" + } + }, + "role": "hub", + "interface": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "MegabitEthernet1/0/1", + "type": "virtual", + "enabled": true + }, + "description": "LAX hub termination for east-west MPLS circuit", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:04.416909Z", + "virtual_circuit_type": { + "name": "EVPN-VXLAN", + "slug": "evpn-vxlan", + "color": "0000ff", + "description": "Data center interconnect using EVPN-VXLAN overlay", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:04.416909Z", + "virtual_device_context": { + "name": "VDC-Production", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "identifier": "1", + "tenant": { + "name": "Tenant 1" + }, + "primary_ip4": { + "address": "192.168.1.1", + "assigned_object_interface": { + "type": "1000base-t", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "eth0" + } + }, + "primary_ip6": { + "address": "2001:db8::1", + "assigned_object_interface": { + "type": "1000base-t", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "eth0" + } + }, + "status": "active", + "description": "Production virtual device context", + "comments": "Isolated network context for production services", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:04.416909Z", + "virtual_disk": { + "virtual_machine": { + "name": "web-server-01", + "status": "active", + "role": { + "name": "Web Server" + }, + "site": { + "name": "Site 1" + } + }, + "name": "root-volume", + "description": "Primary system disk", + "size": "182400", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + } + ], + "id": "f1faa85b-e0a9-4c20-9134-1c86f14f663b", + "sdk_name": "diode-sdk-python-dry-run", + "sdk_version": "0.0.0" + }, + { + "stream": "latest", + "entities": [ + { + "timestamp": "2025-06-13T13:05:05.416909Z", + "virtual_machine": { + "name": "app-server-01", + "status": "active", + "site": { + "name": "Site 1" + }, + "cluster": { + "name": "Cluster 1", + "type": { + "name": "Cluster Type 1" + }, + "scope_site": { + "name": "Site 1" + } + }, + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + }, + "cluster": { + "name": "Cluster 1", + "type": { + "name": "Cluster Type 1" + }, + "scope_site": { + "name": "Site 1" + } + } + }, + "serial": "VM-2023-001", + "role": { + "name": "Application Server" + }, + "tenant": { + "name": "Tenant 1" + }, + "platform": { + "name": "Ubuntu 22.04" + }, + "primary_ip4": { + "address": "192.168.2.99", + "assigned_object_vm_interface": { + "virtual_machine": { + "name": "app-server-01", + "cluster": { + "name": "Cluster 1", + "type": { + "name": "Cluster Type 1" + }, + "scope_site": { + "name": "Site 1" + } + }, + "tenant": { + "name": "Tenant 1" + } + }, + "name": "eth0", + "enabled": true, + "mtu": "1500" + } + }, + "primary_ip6": { + "address": "2001:db8::99", + "assigned_object_vm_interface": { + "virtual_machine": { + "name": "app-server-01", + "cluster": { + "name": "Cluster 1", + "type": { + "name": "Cluster Type 1" + }, + "scope_site": { + "name": "Site 1" + } + }, + "tenant": { + "name": "Tenant 1" + } + }, + "name": "eth0", + "enabled": true, + "mtu": "1500" + } + }, + "vcpus": 4.0, + "memory": "214748364", + "disk": "147483647", + "description": "Primary application server instance", + "comments": "Hosts critical business applications", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:05.416909Z", + "wireless_lan": { + "ssid": "Corp-Secure", + "description": "Corporate secure wireless network", + "group": { + "name": "Corporate Networks", + "slug": "corporate-networks" + }, + "status": "active", + "vlan": { + "vid": 100, + "name": "Production Servers" + }, + "scope_site": { + "name": "Site 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "auth_type": "wpa-enterprise", + "auth_cipher": "aes", + "auth_psk": "SecureWiFiKey123!", + "comments": "Primary corporate wireless network with 802.1X authentication", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:05.416909Z", + "wireless_lan_group": { + "name": "Corporate Networks", + "slug": "corporate-networks", + "parent": { + "name": "All Networks", + "slug": "all-networks" + }, + "description": "Enterprise corporate wireless networks", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "timestamp": "2025-06-13T13:05:05.416909Z", + "wireless_link": { + "interface_a": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Radio0/1", + "type": "ieee802.11ac", + "enabled": true + }, + "interface_b": { + "device": { + "name": "Device 2", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Radio0/1", + "type": "ieee802.11ac", + "enabled": true + }, + "ssid": "P2P-Link-1", + "status": "connected", + "tenant": { + "name": "Tenant 1" + }, + "auth_type": "wpa-personal", + "auth_cipher": "aes", + "auth_psk": "P2PLinkKey123!", + "distance": 1.5, + "distance_unit": "km", + "description": "Point-to-point wireless backhaul link", + "comments": "Building A to Building B wireless bridge", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + } + ], + "id": "2f100ecf-9b81-45e6-bd36-d37e7761db91", + "sdk_name": "diode-sdk-python-dry-run", + "sdk_version": "0.0.0" + } +] \ No newline at end of file From e3c07d17c40a60d20d180b68348f6597a64b9789 Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Fri, 13 Jun 2025 11:06:07 -0300 Subject: [PATCH 13/18] add more complex tests --- tests/test_client.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/test_client.py b/tests/test_client.py index 4dc7c81..5e815ea 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -4,6 +4,7 @@ import json import os +from pathlib import Path from unittest import mock from unittest.mock import MagicMock, patch @@ -514,6 +515,12 @@ def continuation(x, _): ) +@pytest.fixture +def messages_path() -> Path: + """Path to the bundled dry-run messages.""" + return Path(__file__).resolve().parent / "fixtures" / "messages.json" + + @pytest.fixture def mock_diode_authentication(): """ @@ -707,3 +714,38 @@ def test_load_dryrun_entities(tmp_path): assert entities[0].site.name == "Site1" assert isinstance(entities[1], ingester_pb2.Entity) assert entities[1].device.name == "Device1" + + +def test_load_dryrun_entities_from_fixture(messages_path, tmp_path): + """Ensure entities load correctly from the bundled fixture.""" + entities = list(load_dryrun_entities(messages_path)) + + assert len(entities) == 94 + assert isinstance(entities[0], ingester_pb2.Entity) + assert entities[0].asn.asn == 555 + assert entities[33].ip_address.address == "192.168.100.1/24" + assert ( + entities[33].ip_address.assigned_object_interface.name == "GigabitEthernet1/0/1" + ) + assert entities[-1].wireless_link.ssid == "P2P-Link-1" + + output_file = tmp_path / "out.json" + client = DiodeDryRunClient( + dry_run_output_file=str(output_file), + ) + + client._stub = MagicMock() + client.ingest(entities=entities) + assert client._stub.Ingest.call_count == 0 + assert output_file.read_text().startswith("[") + + entities = list(load_dryrun_entities(output_file)) + + assert len(entities) == 94 + assert isinstance(entities[0], ingester_pb2.Entity) + assert entities[0].asn.asn == 555 + assert entities[33].ip_address.address == "192.168.100.1/24" + assert ( + entities[33].ip_address.assigned_object_interface.name == "GigabitEthernet1/0/1" + ) + assert entities[-1].wireless_link.ssid == "P2P-Link-1" From cf901df2061e8015551afe495c756132c336a8f2 Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Fri, 13 Jun 2025 11:20:06 -0300 Subject: [PATCH 14/18] coverage --- tests/test_client.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_client.py b/tests/test_client.py index 5e815ea..d8dba52 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -694,7 +694,8 @@ def test_ingest_dry_run_file(tmp_path): ) client._stub = MagicMock() - client.ingest(entities=[]) + client.ingest(entities=[Entity(site="Site1"), Entity(device="Device1")]) + client.ingest(entities=[Entity(site="Site2"), Entity(device="Device2")]) assert client._stub.Ingest.call_count == 0 assert output_file.read_text().startswith("[") From 347fe61c52d872c538c9e6530ec4fd8cba563f7a Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Fri, 13 Jun 2025 11:22:28 -0300 Subject: [PATCH 15/18] Update netboxlabs/diode/sdk/client.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- netboxlabs/diode/sdk/client.py | 1 + 1 file changed, 1 insertion(+) diff --git a/netboxlabs/diode/sdk/client.py b/netboxlabs/diode/sdk/client.py index cb3d139..cc04328 100644 --- a/netboxlabs/diode/sdk/client.py +++ b/netboxlabs/diode/sdk/client.py @@ -375,6 +375,7 @@ def ingest( ) fh.seek(-2, os.SEEK_END) fh.write(f",\n{output}\n]".encode()) + fh.flush() else: print(output, file=sys.stdout) return ingester_pb2.IngestResponse() From 5f406089c78a8080c9d0c4e8eb9d1bacada46e00 Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:56:28 -0300 Subject: [PATCH 16/18] change output file approach --- README.md | 8 +- netboxlabs/diode/sdk/client.py | 60 +- tests/fixtures/message.json | 3643 ++++++++++++++++++++++++++++++ tests/fixtures/messages.json | 3810 -------------------------------- tests/test_client.py | 39 +- 5 files changed, 3698 insertions(+), 3862 deletions(-) create mode 100644 tests/fixtures/message.json delete mode 100644 tests/fixtures/messages.json diff --git a/README.md b/README.md index d6734e1..4d95f5a 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ pip install netboxlabs-diode-sdk * `DIODE_SENTRY_DSN` - Optional Sentry DSN for error reporting * `DIODE_CLIENT_ID` - Client ID for OAuth2 authentication * `DIODE_CLIENT_SECRET` - Client Secret for OAuth2 authentication -* `DIODE_DRY_RUN_OUTPUT_FILE` - Path to store JSON Lines output when using `DiodeDryRunClient` +* `DIODE_DRY_RUN_OUTPUT_DIR` - Directory where `DiodeDryRunClient` will write JSON files ### Example @@ -80,12 +80,12 @@ if __name__ == "__main__": `DiodeDryRunClient` allows generating ingestion requests without contacting a Diode server. Each request is printed to stdout or written to a JSON Lines file -when `dry_run_output_file` (or `DIODE_DRY_RUN_OUTPUT_FILE`) is set. +when `output_dir` (or `DIODE_DRY_RUN_OUTPUT_FILE`) is set. ```python from netboxlabs.diode.sdk import DiodeDryRunClient -with DiodeDryRunClient(dry_run_output_file="dryrun.json") as client: +with DiodeDryRunClient(app_name="my_app", output_dir="/tmp") as client: client.ingest([ Entity(device="Device A"), ]) @@ -102,7 +102,7 @@ with DiodeClient( app_name="my-test-app", app_version="0.0.1", ) as client: - entities = list(load_dryrun_entities("dryrun.json")) + entities = list(load_dryrun_entities("my_app_92722156890707.json")) client.ingest(entities=entities) ``` diff --git a/netboxlabs/diode/sdk/client.py b/netboxlabs/diode/sdk/client.py index cc04328..85f45b8 100644 --- a/netboxlabs/diode/sdk/client.py +++ b/netboxlabs/diode/sdk/client.py @@ -10,6 +10,7 @@ import platform import ssl import sys +import time import uuid from collections.abc import Iterable from pathlib import Path @@ -30,7 +31,7 @@ _DIODE_SENTRY_DSN_ENVVAR_NAME = "DIODE_SENTRY_DSN" _CLIENT_ID_ENVVAR_NAME = "DIODE_CLIENT_ID" _CLIENT_SECRET_ENVVAR_NAME = "DIODE_CLIENT_SECRET" -_DRY_RUN_OUTPUT_ENVVAR_NAME = "DIODE_DRY_RUN_OUTPUT_FILE" +_DRY_RUN_OUTPUT_DIR_ENVVAR_NAME = "DIODE_DRY_RUN_OUTPUT_DIR" _INGEST_SCOPE = "diode:ingest" _DEFAULT_STREAM = "latest" _LOGGER = logging.getLogger(__name__) @@ -40,11 +41,11 @@ def load_dryrun_entities(file_path: str | Path) -> Iterable[Entity]: """Yield entities from a file with concatenated JSON messages.""" path = Path(file_path) with path.open("r") as fh: - requests = json.load(fh) - for req_dict in requests: - req_pb = ingester_pb2.IngestRequest() - ParseDict(req_dict, req_pb) - yield from req_pb.entities + request = json.load(fh) + req_pb = ingester_pb2.IngestRequest() + ParseDict(request, req_pb) + yield from req_pb.entities + class DiodeClientInterface: """Runtime placeholder for the Diode client interface.""" @@ -315,11 +316,10 @@ class DiodeDryRunClient(DiodeClientInterface): _app_name = None _app_version = None - def __init__(self, dry_run_output_file: str | None = None): + def __init__(self, app_name: str = "dryrun", output_dir: str | None = None): """Initiate a new dry run client.""" - self._dry_run_output_file = os.getenv( - _DRY_RUN_OUTPUT_ENVVAR_NAME, dry_run_output_file - ) + self._output_dir = os.getenv(_DRY_RUN_OUTPUT_DIR_ENVVAR_NAME, output_dir) + self._app_name = app_name @property def name(self) -> str: @@ -332,9 +332,14 @@ def version(self) -> str: return self._version @property - def dry_run_output_file(self) -> str | None: - """Retrieve the dry run output file.""" - return self._dry_run_output_file + def app_name(self) -> str: + """Retrieve the app name.""" + return self._app_name + + @property + def output_dir(self) -> str | None: + """Retrieve the dry run output dir.""" + return self._output_dir def __enter__(self): """Enters the runtime context related to the channel object.""" @@ -352,30 +357,23 @@ def ingest( request = ingester_pb2.IngestRequest( stream=stream, id=str(uuid.uuid4()), + producer_app_name=self._app_name, entities=entities, sdk_name=self.name, sdk_version=self.version, ) output = MessageToJson(request, preserving_proto_field_name=True) - if self._dry_run_output_file: - path = Path(self._dry_run_output_file) - if not path.exists(): - with path.open("w") as fh: - fh.write("[\n") - fh.write(output) - fh.write("\n]") - return ingester_pb2.IngestResponse() - with path.open("rb+") as fh: - fh.seek(-2, os.SEEK_END) - trailer = fh.read(2) - if trailer != b"\n]": - return ingester_pb2.IngestResponse( - errors=["Invalid JSON trailer in dry run output file"] - ) - fh.seek(-2, os.SEEK_END) - fh.write(f",\n{output}\n]".encode()) - fh.flush() + if self._output_dir: + timestamp = time.perf_counter_ns() + path = Path(self._output_dir) + path.mkdir(parents=True, exist_ok=True) + filename = "".join( + c if c.isalnum() or c in ("_", "-") else "_" for c in self._app_name + ) + file_path = path / f"{filename}_{timestamp}.json" + with file_path.open("w") as fh: + fh.write(output) else: print(output, file=sys.stdout) return ingester_pb2.IngestResponse() diff --git a/tests/fixtures/message.json b/tests/fixtures/message.json new file mode 100644 index 0000000..8235e8a --- /dev/null +++ b/tests/fixtures/message.json @@ -0,0 +1,3643 @@ +{ + "stream": "latest", + "entities": [ + { + "asn": { + "asn": "555", + "rir": { + "name": "RIR 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "description": "ASN 555 Description", + "comments": "ASN 555 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "asn_range": { + "name": "ASN Range 1", + "slug": "asn-range-1", + "rir": { + "name": "RIR 1" + }, + "start": "1", + "end": "2", + "tenant": { + "name": "Tenant 1" + }, + "description": "ASN Range 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "aggregate": { + "prefix": "182.82.82.0/24", + "rir": { + "name": "RIR 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "date_added": "2025-04-14T08:08:55Z", + "description": "Aggregate Description", + "comments": "Aggregate Comments", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "circuit": { + "cid": "Circuit 1", + "provider": { + "name": "Provider 1" + }, + "provider_account": { + "provider": { + "name": "Provider 1" + }, + "account": "account1" + }, + "type": { + "name": "Circuit Type 1" + }, + "status": "offline", + "tenant": { + "name": "Tenant 1" + }, + "install_date": "2025-04-14T00:00:00Z", + "termination_date": "2025-04-14T00:00:00Z", + "commit_rate": "10", + "description": "Circuit 1 Description", + "distance": 12.4, + "distance_unit": "ft", + "comments": "Circuit 1 Comments", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "circuit_group": { + "name": "Circuit Group 1", + "description": "Circuit Group 1 Description", + "tenant": { + "name": "Tenant 1" + }, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "circuit_group_assignment": { + "group": { + "name": "Circuit Group 1" + }, + "member_circuit": { + "cid": "Circuit 1", + "type": { + "name": "Circuit Type 1" + }, + "provider": { + "name": "Provider 1" + } + }, + "priority": "tertiary" + } + }, + { + "circuit_group_assignment": { + "group": { + "name": "Circuit Group 1" + }, + "member_virtual_circuit": { + "cid": "Virtual Circuit 1", + "type": { + "name": "Virtual Circuit Type 1" + }, + "provider_network": { + "name": "Provider Network 1", + "provider": { + "name": "Provider 1" + } + } + }, + "priority": "tertiary" + } + }, + { + "circuit_termination": { + "circuit": { + "cid": "Circuit 1", + "type": { + "name": "Circuit Type 1" + }, + "provider": { + "name": "Provider 1" + } + }, + "term_side": "A", + "termination_location": { + "name": "attic", + "site": { + "name": "Site 1" + } + }, + "port_speed": "9600", + "upstream_speed": "14400", + "xconnect_id": "xconnect.1", + "pp_info": "pp info", + "description": "description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "circuit_termination": { + "circuit": { + "cid": "Circuit 1", + "type": { + "name": "Circuit Type 1" + }, + "provider": { + "name": "Provider 1" + } + }, + "term_side": "A", + "termination_provider_network": { + "provider": { + "name": "Provider 1" + }, + "name": "Provider Network 1", + "service_id": "service.1" + }, + "port_speed": "9600", + "upstream_speed": "14400", + "xconnect_id": "xconnect.1", + "pp_info": "pp info", + "description": "description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "circuit_termination": { + "circuit": { + "cid": "Circuit 1", + "type": { + "name": "Circuit Type 1" + }, + "provider": { + "name": "Provider 1" + } + }, + "term_side": "A", + "termination_site": { + "name": "Site 1" + }, + "port_speed": "9600", + "upstream_speed": "14400", + "xconnect_id": "xconnect.1", + "pp_info": "pp info", + "description": "description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "circuit_termination": { + "circuit": { + "cid": "Circuit 1", + "type": { + "name": "Circuit Type 1" + }, + "provider": { + "name": "Provider 1" + } + }, + "term_side": "A", + "termination_site_group": { + "name": "Site Group 1" + }, + "port_speed": "9600", + "upstream_speed": "14400", + "xconnect_id": "xconnect.1", + "pp_info": "pp info", + "description": "description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "circuit_type": { + "name": "Circuit Type 1", + "slug": "circuit-type-1", + "color": "0000ff", + "description": "Circuit Type 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "cluster": { + "name": "Cluster A", + "type": { + "name": "Cluster Type 1" + }, + "group": { + "name": "Cluster Group 1" + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "scope_location": { + "name": "Location 1", + "site": { + "name": "Site 1" + } + }, + "description": "Cluster 1 Description", + "comments": "Cluster 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "cluster": { + "name": "Cluster 2", + "type": { + "name": "Cluster Type 1" + }, + "group": { + "name": "Cluster Group 1" + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "scope_region": { + "name": "Region 1" + }, + "description": "Cluster 1 Description", + "comments": "Cluster 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "cluster": { + "name": "Cluster 3", + "type": { + "name": "Cluster Type 1" + }, + "group": { + "name": "Cluster Group 1" + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "scope_site": { + "name": "Site 1" + }, + "description": "Cluster 1 Description", + "comments": "Cluster 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "cluster": { + "name": "Cluster 4", + "type": { + "name": "Cluster Type 1" + }, + "group": { + "name": "Cluster Group 1" + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "scope_site_group": { + "name": "Site Group 1" + }, + "description": "Cluster 1 Description", + "comments": "Cluster 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "cluster_group": { + "name": "Cluster Group 1", + "description": "Cluster Group 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "cluster_type": { + "name": "Cluster Type 1", + "description": "Cluster Type 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "console_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Manufacturer 1" + }, + "model": "Module Type 1" + } + }, + "name": "Console Port 1", + "label": "Console Port 1 Label", + "type": "db-25", + "speed": "1200", + "description": "Console Port 1 Description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "console_server_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Manufacturer 1" + }, + "model": "Module Type 1" + } + }, + "name": "Console Server Port 1", + "label": "Console Server Port 1 Label", + "type": "db-25", + "speed": "1200", + "description": "Console Server Port 1 Description", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "contact": { + "group": { + "name": "Contact Group 1" + }, + "name": "Contact 1", + "title": "Contact 1 Title", + "phone": "1234567890", + "email": "contact1@example.com", + "address": "1234 Main St, Anytown, USA", + "link": "https://example.com", + "description": "Contact 1 Description", + "comments": "Contact 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "contact_assignment": { + "contact": { + "name": "Contact 1" + }, + "role": { + "name": "Contact Role 1" + }, + "priority": "primary", + "tags": [ + { + "name": "Tag 1" + } + ], + "object_site": { + "name": "Site 1" + } + } + }, + { + "contact_group": { + "name": "Contact Group 1", + "parent": { + "name": "Contact Group 2" + }, + "description": "Contact Group 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "contact_role": { + "name": "Contact Role 1", + "description": "Contact Role 1 Description", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "device": { + "name": "Device ABC", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "platform": { + "name": "Platform 1" + }, + "serial": "1234567890", + "asset_tag": "asset.1", + "site": { + "name": "Site 1" + }, + "location": { + "name": "Location 1", + "site": { + "name": "Site 1" + } + }, + "rack": { + "name": "Rack 1", + "site": { + "name": "Site 1" + }, + "location": { + "name": "Location 1", + "site": { + "name": "Site 1" + } + } + }, + "position": 1.0, + "face": "front", + "latitude": 34.0, + "longitude": 75.0, + "status": "active", + "airflow": "bottom-to-top", + "primary_ip4": { + "address": "192.168.99.1", + "assigned_object_interface": { + "name": "GigabitEthernet1/0/1", + "type": "1000base-t", + "device": { + "name": "Device ABC", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "site": { + "name": "Site 1" + } + } + } + }, + "primary_ip6": { + "address": "2001:ddd::1", + "assigned_object_interface": { + "name": "GigabitEthernet1/0/1", + "type": "1000base-t", + "device": { + "name": "Device ABC", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "site": { + "name": "Site 1" + } + } + } + }, + "cluster": { + "name": "Cluster 1", + "type": { + "name": "Cluster Type 1" + } + }, + "virtual_chassis": { + "name": "Virtual Chassis 1" + }, + "vc_position": "1", + "vc_priority": "1", + "description": "Device 1 Description", + "comments": "Device 1 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "device_bay": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C3P0", + "subdevice_role": "parent" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Device Bay 1", + "label": "Device Bay 1 Label", + "description": "Device Bay 1 Description", + "installed_device": { + "name": "Device 2", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "tags": [ + { + "name": "Tag 1" + } + ] + } + }, + { + "device_role": { + "name": "Core Router", + "slug": "core-router", + "color": "ff0000", + "vm_role": true, + "description": "Primary network routing device", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "default_platform": { + "name": "IOS-XE" + }, + "model": "Catalyst 9300", + "slug": "catalyst-9300", + "part_number": "C9300-48P-E", + "u_height": 1.0, + "exclude_from_utilization": false, + "is_full_depth": true, + "subdevice_role": "parent", + "airflow": "front-to-rear", + "weight": 14.5, + "weight_unit": "lb", + "description": "Enterprise Series Switch", + "comments": "High-performance access switch", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "fhrp_group": { + "name": "HSRP Group 10", + "protocol": "hsrp", + "group_id": "10", + "auth_type": "md5", + "auth_key": "secretkey123", + "description": "Core Router HSRP Group", + "comments": "Primary gateway redundancy group", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "fhrp_group_assignment": { + "group": { + "name": "HSRP Group 10", + "protocol": "hsrp", + "group_id": "10" + }, + "interface_interface": { + "device": { + "name": "Device 1", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "site": { + "name": "Site 1" + } + }, + "name": "GigabitEthernet1/0/1", + "type": "1000base-t", + "enabled": true + }, + "priority": "100" + } + }, + { + "front_port": { + "device": { + "name": "Device 1", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-MODULE" + } + }, + "name": "Front Port 1", + "label": "FP1", + "type": "lc-apc", + "color": "0000ff", + "rear_port": { + "device": { + "name": "Device 1", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Rear Port 1", + "type": "lc-apc" + }, + "rear_port_position": "1", + "description": "Front fiber port", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "ike_policy": { + "name": "IKE-POLICY-1", + "description": "Main IPSec IKE Policy", + "version": "2", + "preshared_key": "secretPSK123!", + "comments": "Primary IKE policy for VPN tunnels", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "proposals": [ + { + "name": "IKE-PROPOSAL-1", + "description": "AES-256 with SHA-256", + "authentication_method": "preshared-keys", + "encryption_algorithm": "aes-256-cbc", + "authentication_algorithm": "hmac-sha256", + "group": "14", + "sa_lifetime": "28800" + } + ] + } + }, + { + "ike_proposal": { + "name": "IKE-PROPOSAL-2", + "description": "High Security IKE Proposal", + "authentication_method": "certificates", + "encryption_algorithm": "aes-256-gcm", + "authentication_algorithm": "hmac-sha512", + "group": "21", + "sa_lifetime": "86400", + "comments": "Enhanced security proposal for critical VPNs", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "ip_address": { + "address": "192.168.100.1/24", + "vrf": { + "name": "PROD-VRF", + "rd": "65000:1" + }, + "tenant": { + "name": "Tenant 1" + }, + "status": "active", + "role": "vip", + "assigned_object_interface": { + "device": { + "name": "Device 1", + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "role": { + "name": "Device Role 1" + }, + "site": { + "name": "Site 1" + } + }, + "name": "GigabitEthernet1/0/1", + "type": "1000base-t" + }, + "nat_inside": { + "address": "10.0.0.1/24" + }, + "dns_name": "prod-vip.example.com", + "description": "Production VIP Address", + "comments": "Primary virtual IP for load balancing", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "ip_range": { + "start_address": "10.100.0.1", + "end_address": "10.100.0.254", + "vrf": { + "name": "PROD-VRF", + "rd": "65000:1" + }, + "tenant": { + "name": "Tenant 1" + }, + "status": "active", + "role": { + "name": "Server Pool", + "slug": "server-pool" + }, + "description": "Production Server IP Range", + "comments": "Allocated for production server deployments", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "mark_utilized": true + } + }, + { + "ip_sec_policy": { + "name": "IPSEC-POLICY-1", + "description": "Site-to-Site VPN Policy", + "pfs_group": "14", + "comments": "High-security IPSec policy for site-to-site VPN", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "proposals": [ + { + "name": "IPSEC-PROPOSAL-1", + "description": "AES-256-GCM with ESP", + "encryption_algorithm": "aes-256-gcm", + "sa_lifetime_seconds": "28800", + "sa_lifetime_data": "28800", + "comments": "Strong encryption proposal for VPN tunnels" + } + ] + } + }, + { + "ip_sec_profile": { + "name": "IPSEC-PROFILE-1", + "description": "Remote Access VPN Profile", + "mode": "esp", + "ike_policy": { + "name": "IKE-POLICY-1", + "version": "2", + "preshared_key": "secretkey123" + }, + "ipsec_policy": { + "name": "IPSEC-POLICY-1", + "description": "Strong encryption policy", + "pfs_group": "14" + }, + "comments": "Standard IPSec profile for remote access VPN tunnels", + "tags": [ + { + "name": "VPN" + }, + { + "name": "Remote-Access" + } + ] + } + }, + { + "ip_sec_proposal": { + "name": "IPSec-Proposal-AES256", + "description": "High security IPSec proposal using AES-256-GCM", + "encryption_algorithm": "aes-256-gcm", + "authentication_algorithm": "hmac-sha512", + "sa_lifetime_seconds": "28800", + "sa_lifetime_data": "42949", + "comments": "Used for critical infrastructure VPNs", + "tags": [ + { + "name": "high-security", + "slug": "high-security", + "color": "0000ff" + }, + { + "name": "production", + "slug": "production", + "color": "0000ff" + } + ] + } + }, + { + "interface": { + "name": "GigabitEthernet1/0/1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-MODULE" + } + }, + "label": "Core Link 1", + "type": "1000base-t", + "enabled": true, + "bridge": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Bridge1", + "type": "bridge" + }, + "lag": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Port-Channel2", + "type": "lag" + }, + "mtu": "9000", + "primary_mac_address": { + "mac_address": "00:11:22:33:44:55" + }, + "speed": "1000000000", + "duplex": "full", + "wwn": "50:01:43:80:00:00:00:00", + "vrf": { + "name": "PROD-VRF", + "rd": "65000:1" + }, + "description": "Core network interface", + "mode": "tagged", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "mgmt_only": false, + "poe_mode": "pse", + "poe_type": "type3-ieee802.3bt", + "untagged_vlan": { + "vid": 100, + "name": "Data VLAN", + "status": "active" + }, + "vlan_translation_policy": { + "name": "Customer Translation Policy", + "description": "VLAN translation for customer traffic" + }, + "vdcs": [ + { + "name": "VDC1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "identifier": 1, + "status": "active", + "description": "Primary VDC" + } + ], + "tagged_vlans": [ + { + "vid": 101, + "name": "Voice VLAN", + "status": "active" + }, + { + "vid": 102, + "name": "Data VLAN", + "status": "active" + } + ] + } + }, + { + "interface": { + "name": "WirelessGigabitEthernet1/0/1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-MODULE" + } + }, + "label": "Core Link 1", + "type": "other-wireless", + "enabled": true, + "bridge": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Bridge1", + "type": "bridge" + }, + "lag": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Port-Channel2", + "type": "lag" + }, + "mtu": "9000", + "primary_mac_address": { + "mac_address": "00:11:22:33:44:55" + }, + "speed": "1000000000", + "duplex": "full", + "wwn": "50:01:43:80:00:00:00:00", + "rf_role": "ap", + "rf_channel": "2.4g-1-2412-22", + "tx_power": "20", + "wireless_lans": [ + { + "ssid": "Corp-Secure", + "description": "Corporate secure wireless network", + "group": { + "name": "Corporate Networks", + "slug": "corporate-networks" + }, + "status": "active", + "vlan": { + "vid": 800, + "name": "Production Servers" + }, + "tenant": { + "name": "Tenant 1" + } + } + ], + "vrf": { + "name": "PROD-VRF" + }, + "description": "Core network interface", + "mode": "access", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "mgmt_only": false, + "untagged_vlan": { + "vid": 900, + "name": "Data VLAN", + "status": "active" + }, + "vlan_translation_policy": { + "name": "Customer Translation Policy", + "description": "VLAN translation for customer traffic" + }, + "vdcs": [ + { + "name": "VDC1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "identifier": 1, + "status": "active", + "description": "Primary VDC" + } + ], + "tagged_vlans": [ + { + "vid": 101, + "name": "Voice VLAN", + "status": "active" + }, + { + "vid": 102, + "name": "Data VLAN", + "status": "active" + } + ] + } + }, + { + "interface": { + "name": "VirtualGigabitEthernet1/0/1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "parent": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Port-Channel1", + "type": "1000base-t" + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-MODULE" + } + }, + "label": "Core Link 1", + "type": "virtual", + "enabled": true, + "bridge": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Bridge1", + "type": "bridge" + }, + "mtu": "9000", + "primary_mac_address": { + "mac_address": "00:11:22:33:44:55" + }, + "speed": "1000000000", + "duplex": "full", + "wwn": "50:01:43:80:00:00:00:00", + "vrf": { + "name": "PROD-VRF" + }, + "description": "Core network interface", + "mode": "q-in-q", + "mark_connected": false, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "mgmt_only": false, + "untagged_vlan": { + "vid": 444, + "name": "Data VLAN", + "status": "active" + }, + "qinq_svlan": { + "vid": 2000, + "name": "Service VLAN", + "status": "active" + }, + "vlan_translation_policy": { + "name": "Customer Translation Policy", + "description": "VLAN translation for customer traffic" + }, + "vdcs": [ + { + "name": "VDC1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "identifier": 1, + "status": "active", + "description": "Primary VDC" + } + ], + "tagged_vlans": [ + { + "vid": 101, + "name": "Voice VLAN", + "status": "active" + }, + { + "vid": 102, + "name": "Data VLAN", + "status": "active" + } + ] + } + }, + { + "inventory_item": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "parent": { + "name": "Chassis 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "name": "Power Supply 1", + "label": "PSU1", + "role": { + "name": "Power Supply", + "color": "00ff00" + }, + "manufacturer": { + "name": "Cisco" + }, + "part_id": "PWR-C1-715WAC", + "serial": "ABC123XYZ", + "asset_tag": "ASSET-001", + "discovered": true, + "description": "715W AC Power Supply", + "status": "active", + "component_power_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "PSU1 Power Port", + "type": "iec-60320-c14", + "maximum_draw": 715, + "allocated_draw": 500, + "description": "Power input port for PSU1" + }, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "inventory_item_role": { + "name": "Line Card", + "slug": "line-card", + "color": "0000ff", + "description": "Network switch line card module", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "l2vpn": { + "name": "Customer-VPLS-1", + "slug": "customer-vpls-1", + "type": "vpls", + "identifier": "65000", + "import_targets": [ + { + "name": "65000:1001", + "description": "Primary import target" + }, + { + "name": "65000:1002", + "description": "Secondary import target" + } + ], + "export_targets": [ + { + "name": "65000:1003", + "description": "Primary export target" + } + ], + "description": "Customer VPLS service for multi-site connectivity", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "l2vpn_termination": { + "l2vpn": { + "name": "Customer-VPLS-1", + "type": "vpls", + "identifier": "65000" + }, + "assigned_object_interface": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "GigabitEthernet1/0/1", + "type": "1000base-t", + "enabled": true + }, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "location": { + "name": "Data Center East Wing", + "slug": "dc-east-wing", + "site": { + "name": "Site 1" + }, + "parent": { + "name": "Main Data Center", + "slug": "main-dc", + "site": { + "name": "Site 1" + } + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "facility": "Building A, Floor 3", + "description": "East wing of the main data center facility", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "mac_address": { + "mac_address": "00:1A:2B:3C:4D:5E", + "assigned_object_interface": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "GigabitEthernet1/0/1", + "type": "1000base-t", + "enabled": true + }, + "description": "Primary management interface MAC", + "comments": "Reserved for network management access", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "manufacturer": { + "name": "Arista Networks", + "slug": "arista-networks", + "description": "Leading provider of cloud networking solutions", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-STACK" + }, + "status": "active", + "serial": "MOD123XYZ", + "asset_tag": "MOD-001", + "description": "Stacking module for switch interconnect", + "comments": "Primary stack member module", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "module_bay": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Stack Module Bay 2", + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-STACK" + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + } + }, + "label": "STACK-2", + "position": "Rear", + "description": "Secondary stacking module bay", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C9300-NM-8X", + "part_number": "C9300-NM-8X=", + "airflow": "front-to-rear", + "weight": 0.7, + "weight_unit": "kg", + "description": "Catalyst 9300 8 x 10GE Network Module", + "comments": "Hot-swappable uplink module for C9300 series switches", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "platform": { + "name": "Cisco IOS-XE", + "slug": "cisco-ios-xe", + "manufacturer": { + "name": "Cisco" + }, + "description": "Enterprise-class IOS operating system for Catalyst switches and ISR routers", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "power_feed": { + "power_panel": { + "site": { + "name": "Site 1" + }, + "name": "Panel A" + }, + "rack": { + "name": "Rack 1", + "site": { + "name": "Site 1" + } + }, + "name": "Power Feed A1", + "status": "active", + "type": "primary", + "supply": "ac", + "phase": "three-phase", + "voltage": "208", + "amperage": "30", + "max_utilization": "80", + "mark_connected": true, + "description": "Primary power feed for network equipment rack", + "tenant": { + "name": "Tenant 1" + }, + "comments": "Connected to UPS system A with redundant backup", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "power_outlet": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "PWR-C1-715WAC" + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + } + }, + "name": "PSU1-Outlet1", + "label": "OUT-1", + "type": "iec-60320-c13", + "color": "0000ff", + "power_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "PSU1" + }, + "feed_leg": "A", + "description": "Power outlet for network switch PSU", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "power_panel": { + "site": { + "name": "Site 1" + }, + "location": { + "name": "Data Center East Wing", + "slug": "dc-east-wing", + "site": { + "name": "Site 1" + } + }, + "name": "Panel B", + "description": "Secondary power distribution panel for network equipment", + "comments": "Connected to redundant UPS system with automatic transfer switch", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "power_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "PWR-C1-715WAC" + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + } + }, + "name": "PSU2", + "label": "PWR-2", + "type": "iec-60320-c14", + "maximum_draw": "715", + "allocated_draw": "650", + "description": "Secondary power supply unit input", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "prefix": { + "prefix": "10.100.0.0/16", + "vrf": { + "name": "PROD-VRF", + "rd": "65000:1" + }, + "scope_site": { + "name": "Site 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "vlan": { + "name": "Production VLAN", + "vid": "112" + }, + "status": "active", + "role": { + "name": "Production", + "slug": "production" + }, + "is_pool": true, + "mark_utilized": true, + "description": "Production network address space", + "comments": "Primary address allocation for production services", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "provider": { + "name": "Level 3 Communications", + "slug": "level3", + "description": "Global Tier 1 Internet Service Provider", + "comments": "Primary transit provider for data center connectivity", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "accounts": [ + { + "provider": { + "name": "Level 3 Communications" + }, + "name": "East Coast Account", + "account": "L3-12345", + "description": "East Coast regional services account", + "comments": "Managed through regional NOC" + }, + { + "provider": { + "name": "Level 3 Communications" + }, + "name": "West Coast Account", + "account": "L3-67890", + "description": "West Coast regional services account", + "comments": "Managed through regional NOC" + } + ], + "asns": [ + { + "asn": "3356", + "rir": { + "name": "ARIN" + }, + "tenant": { + "name": "Tenant 1" + }, + "description": "Level 3 Global ASN", + "comments": "Primary transit ASN" + } + ] + } + }, + { + "provider_account": { + "provider": { + "name": "AT&T" + }, + "name": "Global Enterprise Services", + "account": "ATT-GES-123456", + "description": "Global enterprise services and solutions account", + "comments": "Primary account for worldwide MPLS and managed services", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "provider_network": { + "provider": { + "name": "Level 3 Communications" + }, + "name": "Global MPLS Network", + "service_id": "L3-MPLS-001", + "description": "Global MPLS backbone network", + "comments": "Primary enterprise MPLS network infrastructure", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "rir": { + "name": "ARIN", + "slug": "arin", + "is_private": false, + "description": "American Registry for Internet Numbers", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "rack": { + "name": "Rack 1", + "facility_id": "FAC-001", + "site": { + "name": "Site 1" + }, + "location": { + "name": "Data Center East Wing", + "site": { + "name": "Site 1" + } + }, + "tenant": { + "name": "Tenant 1" + }, + "status": "active", + "role": { + "name": "Server Rack", + "slug": "server-rack", + "color": "0000ff", + "description": "Primary server rack role" + }, + "serial": "RACK123XYZ", + "asset_tag": "RACK-001", + "rack_type": { + "manufacturer": { + "name": "Manufacturer 1" + }, + "model": "R2000", + "slug": "r2000", + "form_factor": "4-post-cabinet" + }, + "form_factor": "4-post-cabinet", + "width": "19", + "u_height": "42", + "starting_unit": "1", + "weight": "350.5", + "max_weight": "1000", + "weight_unit": "lb", + "desc_units": false, + "outer_width": "24", + "outer_depth": "36", + "outer_unit": "in", + "mounting_depth": "30", + "airflow": "front-to-rear", + "description": "Standard 42U server rack", + "comments": "Located in primary data center", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "rack_reservation": { + "rack": { + "name": "Rack 1", + "site": { + "name": "Site 1" + } + }, + "units": [ + "1", + "2", + "3", + "4" + ], + "tenant": { + "name": "Tenant 1" + }, + "description": "Reserved for new server deployment", + "comments": "Project XYZ equipment installation", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "rack_role": { + "name": "Network Equipment", + "slug": "network-equipment", + "color": "0000ff", + "description": "Dedicated racks for network infrastructure", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "rack_type": { + "manufacturer": { + "name": "Manufacturer 1" + }, + "model": "R2000", + "slug": "r2000", + "description": "Standard 42U server rack", + "form_factor": "4-post-cabinet", + "width": "19", + "u_height": "42", + "starting_unit": "1", + "desc_units": false, + "outer_width": "24", + "outer_depth": "36", + "outer_unit": "in", + "weight": 350.5, + "max_weight": "1000", + "weight_unit": "lb", + "mounting_depth": "30", + "comments": "Standard enterprise rack configuration", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "rear_port": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module": { + "asset_tag": "module-1234567890", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "module_bay": { + "name": "Module Bay 1", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + } + }, + "module_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S-MODULE" + } + }, + "name": "Rear Port 1", + "label": "RP1", + "type": "lc-apc", + "color": "ff00ff", + "positions": "1", + "description": "Rear fiber port", + "mark_connected": true, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "region": { + "name": "North America", + "slug": "north-america", + "parent": { + "name": "Global", + "slug": "global", + "description": "Global Region", + "tags": [ + { + "name": "Tag 1" + } + ] + }, + "description": "North American Region", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "role": { + "name": "Network Administrator", + "slug": "network-admin", + "weight": "1000", + "description": "Primary network administration role", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "route_target": { + "name": "65000:3001", + "tenant": { + "name": "Tenant 1" + }, + "description": "Primary route target for MPLS VPN", + "comments": "Used for customer VPN service", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "service": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Web Server", + "protocol": "tcp", + "ports": [ + "80", + "443" + ], + "description": "Primary web server service", + "comments": "Handles HTTPS traffic for main website", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "ipaddresses": [ + { + "address": "192.168.1.100/24", + "status": "active", + "dns_name": "web.example.com" + } + ] + } + }, + { + "site": { + "name": "Data Center West", + "slug": "dc-west", + "status": "active", + "region": { + "name": "North America", + "slug": "north-america" + }, + "group": { + "name": "Primary Data Centers", + "slug": "primary-dcs" + }, + "tenant": { + "name": "Tenant 1" + }, + "facility": "Building 7", + "time_zone": "America/Los_Angeles", + "description": "Primary West Coast Data Center", + "physical_address": "123 Tech Drive, San Jose, CA 95134", + "shipping_address": "Receiving Dock 3, 123 Tech Drive, San Jose, CA 95134", + "latitude": 37.3382, + "longitude": -121.8863, + "comments": "24x7 access requires security clearance", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "asns": [ + { + "asn": "555", + "rir": { + "name": "RIR 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "description": "ASN 555 Description", + "comments": "ASN 555 Comments", + "tags": [ + { + "name": "Tag 1" + } + ] + } + ] + } + }, + { + "site_group": { + "name": "Global Data Centers", + "slug": "global-dcs", + "parent": { + "name": "Infrastructure", + "slug": "infrastructure" + }, + "description": "Worldwide data center facilities", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "tag": { + "name": "Production", + "slug": "production", + "color": "ff0000" + } + }, + { + "tenant": { + "name": "Acme Corporation", + "slug": "acme-corp", + "group": { + "name": "Enterprise Customers", + "slug": "enterprise-customers" + }, + "description": "Global technology solutions provider", + "comments": "Fortune 500 company with worldwide operations", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "tenant_group": { + "name": "Financial Services", + "slug": "financial-services", + "parent": { + "name": "Enterprise Sectors", + "slug": "enterprise-sectors" + }, + "description": "Banking and financial industry customers", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "tunnel": { + "name": "DC-West-to-East-Primary", + "status": "active", + "group": { + "name": "Inter-DC Tunnels", + "slug": "inter-dc-tunnels" + }, + "encapsulation": "ipsec-tunnel", + "ipsec_profile": { + "name": "IPSEC-PROFILE-1", + "mode": "esp", + "ike_policy": { + "name": "IKE-POLICY-TUN-1", + "version": "2", + "preshared_key": "1234567890", + "comments": "Using AES-256-GCM encryption with PFS" + }, + "ipsec_policy": { + "name": "IPSEC-POLICY-1", + "pfs_group": "2" + } + }, + "tenant": { + "name": "Tenant 1" + }, + "tunnel_id": "1001", + "description": "Primary IPSec tunnel between West and East data centers", + "comments": "Using AES-256-GCM encryption with PFS", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "tunnel_group": { + "name": "Regional Backbones", + "slug": "regional-backbones", + "description": "High-capacity encrypted tunnels between regional data centers", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "tunnel_termination": { + "tunnel": { + "name": "DC-West-to-East-Primary", + "status": "active", + "encapsulation": "ipsec-tunnel" + }, + "role": "hub", + "termination_device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "outside_ip": { + "address": "203.0.113.1/24", + "status": "active", + "dns_name": "vpn1.example.com" + }, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "vlan": { + "group": { + "name": "Production VLANs", + "slug": "production-vlans" + }, + "vid": "807", + "name": "Production Servers", + "tenant": { + "name": "Tenant 1" + }, + "status": "active", + "role": { + "name": "Production", + "slug": "production" + }, + "description": "Primary production server network", + "qinq_role": "cvlan", + "qinq_svlan": { + "vid": "1909", + "name": "Service Provider VLAN" + }, + "comments": "Used for customer-facing production workloads", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "vlan_group": { + "name": "Data Center Core", + "slug": "dc-core", + "scope_site": { + "name": "Data Center West", + "slug": "dc-west", + "status": "active" + }, + "description": "Core network VLANs for data center infrastructure", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "vlan_translation_policy": { + "name": "Customer Edge Translation", + "description": "VLAN translation policy for customer edge interfaces" + } + }, + { + "vlan_translation_rule": { + "policy": { + "name": "Customer Edge Translation", + "description": "VLAN translation policy for customer edge interfaces" + }, + "local_vid": "100", + "remote_vid": "1100", + "description": "Map customer VLAN 100 to provider VLAN 1100" + } + }, + { + "vm_interface": { + "virtual_machine": { + "name": "web-server-01", + "status": "active", + "role": { + "name": "Web Server" + }, + "site": { + "name": "Site 1" + } + }, + "name": "eth0", + "enabled": true, + "parent": { + "virtual_machine": { + "name": "web-server-01", + "status": "active", + "role": { + "name": "Web Server" + }, + "site": { + "name": "Site 1" + } + }, + "name": "bond0" + }, + "bridge": { + "virtual_machine": { + "name": "web-server-01", + "status": "active", + "role": { + "name": "Web Server" + }, + "site": { + "name": "Site 1" + } + }, + "name": "br0" + }, + "mtu": "9000", + "primary_mac_address": { + "mac_address": "00:1A:2B:3C:4D:5E" + }, + "description": "Primary network interface", + "mode": "q-in-q", + "untagged_vlan": { + "vid": "1101", + "name": "Production Servers" + }, + "qinq_svlan": { + "vid": "1000", + "name": "Service Provider VLAN" + }, + "vlan_translation_policy": { + "name": "Customer Edge Translation" + }, + "vrf": { + "name": "PROD-VRF", + "rd": "65000:1" + }, + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "vrf": { + "name": "Customer-A-VRF", + "rd": "65000:100", + "tenant": { + "name": "Tenant 1" + }, + "enforce_unique": true, + "description": "Isolated routing domain for Customer A", + "comments": "Used for customer's private network services", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ], + "import_targets": [ + { + "name": "65000:100" + }, + { + "name": "65000:101" + } + ], + "export_targets": [ + { + "name": "65000:103" + } + ] + } + }, + { + "virtual_chassis": { + "name": "Stack-DC1-Core", + "domain": "dc1-core.example.com", + "master": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "description": "Core switch stack in DC1", + "comments": "Primary switching infrastructure for data center 1", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "virtual_circuit": { + "cid": "VC-001-LAX-NYC", + "provider_network": { + "provider": { + "name": "Level 3 Communications" + }, + "name": "Global MPLS Network", + "service_id": "L3-MPLS-001" + }, + "provider_account": { + "provider": { + "name": "Level 3 Communications" + }, + "name": "East Coast Account", + "account": "L3-12345" + }, + "type": { + "name": "MPLS L3VPN", + "slug": "mpls-l3vpn" + }, + "status": "active", + "tenant": { + "name": "Tenant 1" + }, + "description": "LAX to NYC MPLS circuit", + "comments": "Primary east-west connectivity", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "virtual_circuit_termination": { + "virtual_circuit": { + "cid": "VC-001-LAX-NYC", + "provider_network": { + "provider": { + "name": "Level 3 Communications" + }, + "name": "Global MPLS Network" + }, + "type": { + "name": "MPLS L3VPN", + "slug": "mpls-l3vpn" + } + }, + "role": "hub", + "interface": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "MegabitEthernet1/0/1", + "type": "virtual", + "enabled": true + }, + "description": "LAX hub termination for east-west MPLS circuit", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "virtual_circuit_type": { + "name": "EVPN-VXLAN", + "slug": "evpn-vxlan", + "color": "0000ff", + "description": "Data center interconnect using EVPN-VXLAN overlay", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "virtual_device_context": { + "name": "VDC-Production", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "identifier": "1", + "tenant": { + "name": "Tenant 1" + }, + "primary_ip4": { + "address": "192.168.1.1", + "assigned_object_interface": { + "type": "1000base-t", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "eth0" + } + }, + "primary_ip6": { + "address": "2001:db8::1", + "assigned_object_interface": { + "type": "1000base-t", + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "eth0" + } + }, + "status": "active", + "description": "Production virtual device context", + "comments": "Isolated network context for production services", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "virtual_disk": { + "virtual_machine": { + "name": "web-server-01", + "status": "active", + "role": { + "name": "Web Server" + }, + "site": { + "name": "Site 1" + } + }, + "name": "root-volume", + "description": "Primary system disk", + "size": "182400", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "virtual_machine": { + "name": "app-server-01", + "status": "active", + "site": { + "name": "Site 1" + }, + "cluster": { + "name": "Cluster 1", + "type": { + "name": "Cluster Type 1" + }, + "scope_site": { + "name": "Site 1" + } + }, + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + }, + "cluster": { + "name": "Cluster 1", + "type": { + "name": "Cluster Type 1" + }, + "scope_site": { + "name": "Site 1" + } + } + }, + "serial": "VM-2023-001", + "role": { + "name": "Application Server" + }, + "tenant": { + "name": "Tenant 1" + }, + "platform": { + "name": "Ubuntu 22.04" + }, + "primary_ip4": { + "address": "192.168.2.99", + "assigned_object_vm_interface": { + "virtual_machine": { + "name": "app-server-01", + "cluster": { + "name": "Cluster 1", + "type": { + "name": "Cluster Type 1" + }, + "scope_site": { + "name": "Site 1" + } + }, + "tenant": { + "name": "Tenant 1" + } + }, + "name": "eth0", + "enabled": true, + "mtu": "1500" + } + }, + "primary_ip6": { + "address": "2001:db8::99", + "assigned_object_vm_interface": { + "virtual_machine": { + "name": "app-server-01", + "cluster": { + "name": "Cluster 1", + "type": { + "name": "Cluster Type 1" + }, + "scope_site": { + "name": "Site 1" + } + }, + "tenant": { + "name": "Tenant 1" + } + }, + "name": "eth0", + "enabled": true, + "mtu": "1500" + } + }, + "vcpus": 4.0, + "memory": "214748364", + "disk": "147483647", + "description": "Primary application server instance", + "comments": "Hosts critical business applications", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "wireless_lan": { + "ssid": "Corp-Secure", + "description": "Corporate secure wireless network", + "group": { + "name": "Corporate Networks", + "slug": "corporate-networks" + }, + "status": "active", + "vlan": { + "vid": 100, + "name": "Production Servers" + }, + "scope_site": { + "name": "Site 1" + }, + "tenant": { + "name": "Tenant 1" + }, + "auth_type": "wpa-enterprise", + "auth_cipher": "aes", + "auth_psk": "SecureWiFiKey123!", + "comments": "Primary corporate wireless network with 802.1X authentication", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "wireless_lan_group": { + "name": "Corporate Networks", + "slug": "corporate-networks", + "parent": { + "name": "All Networks", + "slug": "all-networks" + }, + "description": "Enterprise corporate wireless networks", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + }, + { + "wireless_link": { + "interface_a": { + "device": { + "name": "Device 1", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Radio0/1", + "type": "ieee802.11ac", + "enabled": true + }, + "interface_b": { + "device": { + "name": "Device 2", + "role": { + "name": "Device Role 1" + }, + "device_type": { + "manufacturer": { + "name": "Cisco" + }, + "model": "C2960S" + }, + "site": { + "name": "Site 1" + } + }, + "name": "Radio0/1", + "type": "ieee802.11ac", + "enabled": true + }, + "ssid": "P2P-Link-1", + "status": "connected", + "tenant": { + "name": "Tenant 1" + }, + "auth_type": "wpa-personal", + "auth_cipher": "aes", + "auth_psk": "P2PLinkKey123!", + "distance": 1.5, + "distance_unit": "km", + "description": "Point-to-point wireless backhaul link", + "comments": "Building A to Building B wireless bridge", + "tags": [ + { + "name": "Tag 1" + }, + { + "name": "Tag 2" + } + ] + } + } + ], + "id": "f87ea004-45e3-4c61-b75b-02116ae9c3b2", + "sdk_name": "diode-sdk-python-dry-run", + "producer_app_name": "dryrun", + "sdk_version": "1.2.0" +} \ No newline at end of file diff --git a/tests/fixtures/messages.json b/tests/fixtures/messages.json deleted file mode 100644 index 7fd4738..0000000 --- a/tests/fixtures/messages.json +++ /dev/null @@ -1,3810 +0,0 @@ -[ - { - "stream": "latest", - "entities": [ - { - "timestamp": "2025-06-13T13:04:56.416909Z", - "asn": { - "asn": "555", - "rir": { - "name": "RIR 1" - }, - "tenant": { - "name": "Tenant 1" - }, - "description": "ASN 555 Description", - "comments": "ASN 555 Comments", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:56.416909Z", - "asn_range": { - "name": "ASN Range 1", - "slug": "asn-range-1", - "rir": { - "name": "RIR 1" - }, - "start": "1", - "end": "2", - "tenant": { - "name": "Tenant 1" - }, - "description": "ASN Range 1 Description", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:56.416909Z", - "aggregate": { - "prefix": "182.82.82.0/24", - "rir": { - "name": "RIR 1" - }, - "tenant": { - "name": "Tenant 1" - }, - "date_added": "2025-04-14T08:08:55Z", - "description": "Aggregate Description", - "comments": "Aggregate Comments", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:56.416909Z", - "circuit": { - "cid": "Circuit 1", - "provider": { - "name": "Provider 1" - }, - "provider_account": { - "provider": { - "name": "Provider 1" - }, - "account": "account1" - }, - "type": { - "name": "Circuit Type 1" - }, - "status": "offline", - "tenant": { - "name": "Tenant 1" - }, - "install_date": "2025-04-14T00:00:00Z", - "termination_date": "2025-04-14T00:00:00Z", - "commit_rate": "10", - "description": "Circuit 1 Description", - "distance": 12.4, - "distance_unit": "ft", - "comments": "Circuit 1 Comments", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:56.416909Z", - "circuit_group": { - "name": "Circuit Group 1", - "description": "Circuit Group 1 Description", - "tenant": { - "name": "Tenant 1" - }, - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:56.416909Z", - "circuit_group_assignment": { - "group": { - "name": "Circuit Group 1" - }, - "member_circuit": { - "cid": "Circuit 1", - "type": { - "name": "Circuit Type 1" - }, - "provider": { - "name": "Provider 1" - } - }, - "priority": "tertiary" - } - }, - { - "timestamp": "2025-06-13T13:04:56.416909Z", - "circuit_group_assignment": { - "group": { - "name": "Circuit Group 1" - }, - "member_virtual_circuit": { - "cid": "Virtual Circuit 1", - "type": { - "name": "Virtual Circuit Type 1" - }, - "provider_network": { - "name": "Provider Network 1", - "provider": { - "name": "Provider 1" - } - } - }, - "priority": "tertiary" - } - }, - { - "timestamp": "2025-06-13T13:04:56.416909Z", - "circuit_termination": { - "circuit": { - "cid": "Circuit 1", - "type": { - "name": "Circuit Type 1" - }, - "provider": { - "name": "Provider 1" - } - }, - "term_side": "A", - "termination_location": { - "name": "attic", - "site": { - "name": "Site 1" - } - }, - "port_speed": "9600", - "upstream_speed": "14400", - "xconnect_id": "xconnect.1", - "pp_info": "pp info", - "description": "description", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:56.416909Z", - "circuit_termination": { - "circuit": { - "cid": "Circuit 1", - "type": { - "name": "Circuit Type 1" - }, - "provider": { - "name": "Provider 1" - } - }, - "term_side": "A", - "termination_provider_network": { - "provider": { - "name": "Provider 1" - }, - "name": "Provider Network 1", - "service_id": "service.1" - }, - "port_speed": "9600", - "upstream_speed": "14400", - "xconnect_id": "xconnect.1", - "pp_info": "pp info", - "description": "description", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:56.416909Z", - "circuit_termination": { - "circuit": { - "cid": "Circuit 1", - "type": { - "name": "Circuit Type 1" - }, - "provider": { - "name": "Provider 1" - } - }, - "term_side": "A", - "termination_site": { - "name": "Site 1" - }, - "port_speed": "9600", - "upstream_speed": "14400", - "xconnect_id": "xconnect.1", - "pp_info": "pp info", - "description": "description", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - } - ] - } - } - ], - "id": "ae9c981f-685c-4fbc-b9ce-b5fa00135b8c", - "sdk_name": "diode-sdk-python-dry-run", - "sdk_version": "0.0.0" - }, - { - "stream": "latest", - "entities": [ - { - "timestamp": "2025-06-13T13:04:57.416909Z", - "circuit_termination": { - "circuit": { - "cid": "Circuit 1", - "type": { - "name": "Circuit Type 1" - }, - "provider": { - "name": "Provider 1" - } - }, - "term_side": "A", - "termination_site_group": { - "name": "Site Group 1" - }, - "port_speed": "9600", - "upstream_speed": "14400", - "xconnect_id": "xconnect.1", - "pp_info": "pp info", - "description": "description", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:57.416909Z", - "circuit_type": { - "name": "Circuit Type 1", - "slug": "circuit-type-1", - "color": "0000ff", - "description": "Circuit Type 1 Description", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:57.416909Z", - "cluster": { - "name": "Cluster A", - "type": { - "name": "Cluster Type 1" - }, - "group": { - "name": "Cluster Group 1" - }, - "status": "active", - "tenant": { - "name": "Tenant 1" - }, - "scope_location": { - "name": "Location 1", - "site": { - "name": "Site 1" - } - }, - "description": "Cluster 1 Description", - "comments": "Cluster 1 Comments", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:57.416909Z", - "cluster": { - "name": "Cluster 2", - "type": { - "name": "Cluster Type 1" - }, - "group": { - "name": "Cluster Group 1" - }, - "status": "active", - "tenant": { - "name": "Tenant 1" - }, - "scope_region": { - "name": "Region 1" - }, - "description": "Cluster 1 Description", - "comments": "Cluster 1 Comments", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:57.416909Z", - "cluster": { - "name": "Cluster 3", - "type": { - "name": "Cluster Type 1" - }, - "group": { - "name": "Cluster Group 1" - }, - "status": "active", - "tenant": { - "name": "Tenant 1" - }, - "scope_site": { - "name": "Site 1" - }, - "description": "Cluster 1 Description", - "comments": "Cluster 1 Comments", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:57.416909Z", - "cluster": { - "name": "Cluster 4", - "type": { - "name": "Cluster Type 1" - }, - "group": { - "name": "Cluster Group 1" - }, - "status": "active", - "tenant": { - "name": "Tenant 1" - }, - "scope_site_group": { - "name": "Site Group 1" - }, - "description": "Cluster 1 Description", - "comments": "Cluster 1 Comments", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:57.416909Z", - "cluster_group": { - "name": "Cluster Group 1", - "description": "Cluster Group 1 Description", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:57.416909Z", - "cluster_type": { - "name": "Cluster Type 1", - "description": "Cluster Type 1 Description", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:57.416909Z", - "console_port": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - }, - "module_type": { - "manufacturer": { - "name": "Manufacturer 1" - }, - "model": "Module Type 1" - } - }, - "name": "Console Port 1", - "label": "Console Port 1 Label", - "type": "db-25", - "speed": "1200", - "description": "Console Port 1 Description", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:57.416909Z", - "console_server_port": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - }, - "module_type": { - "manufacturer": { - "name": "Manufacturer 1" - }, - "model": "Module Type 1" - } - }, - "name": "Console Server Port 1", - "label": "Console Server Port 1 Label", - "type": "db-25", - "speed": "1200", - "description": "Console Server Port 1 Description", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - } - ] - } - } - ], - "id": "029704fa-d34d-4d8b-a8e0-87ccdd3cb811", - "sdk_name": "diode-sdk-python-dry-run", - "sdk_version": "0.0.0" - }, - { - "stream": "latest", - "entities": [ - { - "timestamp": "2025-06-13T13:04:58.416909Z", - "contact": { - "group": { - "name": "Contact Group 1" - }, - "name": "Contact 1", - "title": "Contact 1 Title", - "phone": "1234567890", - "email": "contact1@example.com", - "address": "1234 Main St, Anytown, USA", - "link": "https://example.com", - "description": "Contact 1 Description", - "comments": "Contact 1 Comments", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:58.416909Z", - "contact_assignment": { - "contact": { - "name": "Contact 1" - }, - "role": { - "name": "Contact Role 1" - }, - "priority": "primary", - "tags": [ - { - "name": "Tag 1" - } - ], - "object_site": { - "name": "Site 1" - } - } - }, - { - "timestamp": "2025-06-13T13:04:58.416909Z", - "contact_group": { - "name": "Contact Group 1", - "parent": { - "name": "Contact Group 2" - }, - "description": "Contact Group 1 Description", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:58.416909Z", - "contact_role": { - "name": "Contact Role 1", - "description": "Contact Role 1 Description", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:58.416909Z", - "device": { - "name": "Device ABC", - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "role": { - "name": "Device Role 1" - }, - "tenant": { - "name": "Tenant 1" - }, - "platform": { - "name": "Platform 1" - }, - "serial": "1234567890", - "asset_tag": "asset.1", - "site": { - "name": "Site 1" - }, - "location": { - "name": "Location 1", - "site": { - "name": "Site 1" - } - }, - "rack": { - "name": "Rack 1", - "site": { - "name": "Site 1" - }, - "location": { - "name": "Location 1", - "site": { - "name": "Site 1" - } - } - }, - "position": 1.0, - "face": "front", - "latitude": 34.0, - "longitude": 75.0, - "status": "active", - "airflow": "bottom-to-top", - "primary_ip4": { - "address": "192.168.99.1", - "assigned_object_interface": { - "name": "GigabitEthernet1/0/1", - "type": "1000base-t", - "device": { - "name": "Device ABC", - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "role": { - "name": "Device Role 1" - }, - "tenant": { - "name": "Tenant 1" - }, - "site": { - "name": "Site 1" - } - } - } - }, - "primary_ip6": { - "address": "2001:ddd::1", - "assigned_object_interface": { - "name": "GigabitEthernet1/0/1", - "type": "1000base-t", - "device": { - "name": "Device ABC", - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "role": { - "name": "Device Role 1" - }, - "tenant": { - "name": "Tenant 1" - }, - "site": { - "name": "Site 1" - } - } - } - }, - "cluster": { - "name": "Cluster 1", - "type": { - "name": "Cluster Type 1" - } - }, - "virtual_chassis": { - "name": "Virtual Chassis 1" - }, - "vc_position": "1", - "vc_priority": "1", - "description": "Device 1 Description", - "comments": "Device 1 Comments", - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:58.416909Z", - "device_bay": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C3P0", - "subdevice_role": "parent" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Device Bay 1", - "label": "Device Bay 1 Label", - "description": "Device Bay 1 Description", - "installed_device": { - "name": "Device 2", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "tags": [ - { - "name": "Tag 1" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:58.416909Z", - "device_role": { - "name": "Core Router", - "slug": "core-router", - "color": "ff0000", - "vm_role": true, - "description": "Primary network routing device", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:58.416909Z", - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "default_platform": { - "name": "IOS-XE" - }, - "model": "Catalyst 9300", - "slug": "catalyst-9300", - "part_number": "C9300-48P-E", - "u_height": 1.0, - "exclude_from_utilization": false, - "is_full_depth": true, - "subdevice_role": "parent", - "airflow": "front-to-rear", - "weight": 14.5, - "weight_unit": "lb", - "description": "Enterprise Series Switch", - "comments": "High-performance access switch", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:58.416909Z", - "fhrp_group": { - "name": "HSRP Group 10", - "protocol": "hsrp", - "group_id": "10", - "auth_type": "md5", - "auth_key": "secretkey123", - "description": "Core Router HSRP Group", - "comments": "Primary gateway redundancy group", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:58.416909Z", - "fhrp_group_assignment": { - "group": { - "name": "HSRP Group 10", - "protocol": "hsrp", - "group_id": "10" - }, - "interface_interface": { - "device": { - "name": "Device 1", - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "role": { - "name": "Device Role 1" - }, - "site": { - "name": "Site 1" - } - }, - "name": "GigabitEthernet1/0/1", - "type": "1000base-t", - "enabled": true - }, - "priority": "100" - } - } - ], - "id": "6cbad6f7-e950-40c8-b6cb-4f1603629dd8", - "sdk_name": "diode-sdk-python-dry-run", - "sdk_version": "0.0.0" - }, - { - "stream": "latest", - "entities": [ - { - "timestamp": "2025-06-13T13:04:59.416909Z", - "front_port": { - "device": { - "name": "Device 1", - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "role": { - "name": "Device Role 1" - }, - "site": { - "name": "Site 1" - } - }, - "module": { - "device": { - "name": "Device 1", - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "role": { - "name": "Device Role 1" - }, - "site": { - "name": "Site 1" - } - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - }, - "module_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S-MODULE" - } - }, - "name": "Front Port 1", - "label": "FP1", - "type": "lc-apc", - "color": "0000ff", - "rear_port": { - "device": { - "name": "Device 1", - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "role": { - "name": "Device Role 1" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Rear Port 1", - "type": "lc-apc" - }, - "rear_port_position": "1", - "description": "Front fiber port", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:59.416909Z", - "ike_policy": { - "name": "IKE-POLICY-1", - "description": "Main IPSec IKE Policy", - "version": "2", - "preshared_key": "secretPSK123!", - "comments": "Primary IKE policy for VPN tunnels", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ], - "proposals": [ - { - "name": "IKE-PROPOSAL-1", - "description": "AES-256 with SHA-256", - "authentication_method": "preshared-keys", - "encryption_algorithm": "aes-256-cbc", - "authentication_algorithm": "hmac-sha256", - "group": "14", - "sa_lifetime": "28800" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:59.416909Z", - "ike_proposal": { - "name": "IKE-PROPOSAL-2", - "description": "High Security IKE Proposal", - "authentication_method": "certificates", - "encryption_algorithm": "aes-256-gcm", - "authentication_algorithm": "hmac-sha512", - "group": "21", - "sa_lifetime": "86400", - "comments": "Enhanced security proposal for critical VPNs", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:59.416909Z", - "ip_address": { - "address": "192.168.100.1/24", - "vrf": { - "name": "PROD-VRF", - "rd": "65000:1" - }, - "tenant": { - "name": "Tenant 1" - }, - "status": "active", - "role": "vip", - "assigned_object_interface": { - "device": { - "name": "Device 1", - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "role": { - "name": "Device Role 1" - }, - "site": { - "name": "Site 1" - } - }, - "name": "GigabitEthernet1/0/1", - "type": "1000base-t" - }, - "nat_inside": { - "address": "10.0.0.1/24" - }, - "dns_name": "prod-vip.example.com", - "description": "Production VIP Address", - "comments": "Primary virtual IP for load balancing", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:59.416909Z", - "ip_range": { - "start_address": "10.100.0.1", - "end_address": "10.100.0.254", - "vrf": { - "name": "PROD-VRF", - "rd": "65000:1" - }, - "tenant": { - "name": "Tenant 1" - }, - "status": "active", - "role": { - "name": "Server Pool", - "slug": "server-pool" - }, - "description": "Production Server IP Range", - "comments": "Allocated for production server deployments", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ], - "mark_utilized": true - } - }, - { - "timestamp": "2025-06-13T13:04:59.416909Z", - "ip_sec_policy": { - "name": "IPSEC-POLICY-1", - "description": "Site-to-Site VPN Policy", - "pfs_group": "14", - "comments": "High-security IPSec policy for site-to-site VPN", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ], - "proposals": [ - { - "name": "IPSEC-PROPOSAL-1", - "description": "AES-256-GCM with ESP", - "encryption_algorithm": "aes-256-gcm", - "sa_lifetime_seconds": "28800", - "sa_lifetime_data": "28800", - "comments": "Strong encryption proposal for VPN tunnels" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:59.416909Z", - "ip_sec_profile": { - "name": "IPSEC-PROFILE-1", - "description": "Remote Access VPN Profile", - "mode": "esp", - "ike_policy": { - "name": "IKE-POLICY-1", - "version": "2", - "preshared_key": "secretkey123" - }, - "ipsec_policy": { - "name": "IPSEC-POLICY-1", - "description": "Strong encryption policy", - "pfs_group": "14" - }, - "comments": "Standard IPSec profile for remote access VPN tunnels", - "tags": [ - { - "name": "VPN" - }, - { - "name": "Remote-Access" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:59.416909Z", - "ip_sec_proposal": { - "name": "IPSec-Proposal-AES256", - "description": "High security IPSec proposal using AES-256-GCM", - "encryption_algorithm": "aes-256-gcm", - "authentication_algorithm": "hmac-sha512", - "sa_lifetime_seconds": "28800", - "sa_lifetime_data": "42949", - "comments": "Used for critical infrastructure VPNs", - "tags": [ - { - "name": "high-security", - "slug": "high-security", - "color": "0000ff" - }, - { - "name": "production", - "slug": "production", - "color": "0000ff" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:59.416909Z", - "interface": { - "name": "GigabitEthernet1/0/1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - }, - "module_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S-MODULE" - } - }, - "label": "Core Link 1", - "type": "1000base-t", - "enabled": true, - "bridge": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Bridge1", - "type": "bridge" - }, - "lag": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Port-Channel2", - "type": "lag" - }, - "mtu": "9000", - "primary_mac_address": { - "mac_address": "00:11:22:33:44:55" - }, - "speed": "1000000000", - "duplex": "full", - "wwn": "50:01:43:80:00:00:00:00", - "vrf": { - "name": "PROD-VRF", - "rd": "65000:1" - }, - "description": "Core network interface", - "mode": "tagged", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ], - "mgmt_only": false, - "poe_mode": "pse", - "poe_type": "type3-ieee802.3bt", - "untagged_vlan": { - "vid": 100, - "name": "Data VLAN", - "status": "active" - }, - "vlan_translation_policy": { - "name": "Customer Translation Policy", - "description": "VLAN translation for customer traffic" - }, - "vdcs": [ - { - "name": "VDC1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "identifier": 1, - "status": "active", - "description": "Primary VDC" - } - ], - "tagged_vlans": [ - { - "vid": 101, - "name": "Voice VLAN", - "status": "active" - }, - { - "vid": 102, - "name": "Data VLAN", - "status": "active" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:04:59.416909Z", - "interface": { - "name": "WirelessGigabitEthernet1/0/1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - }, - "module_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S-MODULE" - } - }, - "label": "Core Link 1", - "type": "other-wireless", - "enabled": true, - "bridge": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Bridge1", - "type": "bridge" - }, - "lag": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Port-Channel2", - "type": "lag" - }, - "mtu": "9000", - "primary_mac_address": { - "mac_address": "00:11:22:33:44:55" - }, - "speed": "1000000000", - "duplex": "full", - "wwn": "50:01:43:80:00:00:00:00", - "rf_role": "ap", - "rf_channel": "2.4g-1-2412-22", - "tx_power": "20", - "wireless_lans": [ - { - "ssid": "Corp-Secure", - "description": "Corporate secure wireless network", - "group": { - "name": "Corporate Networks", - "slug": "corporate-networks" - }, - "status": "active", - "vlan": { - "vid": 800, - "name": "Production Servers" - }, - "tenant": { - "name": "Tenant 1" - } - } - ], - "vrf": { - "name": "PROD-VRF" - }, - "description": "Core network interface", - "mode": "access", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ], - "mgmt_only": false, - "untagged_vlan": { - "vid": 900, - "name": "Data VLAN", - "status": "active" - }, - "vlan_translation_policy": { - "name": "Customer Translation Policy", - "description": "VLAN translation for customer traffic" - }, - "vdcs": [ - { - "name": "VDC1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "identifier": 1, - "status": "active", - "description": "Primary VDC" - } - ], - "tagged_vlans": [ - { - "vid": 101, - "name": "Voice VLAN", - "status": "active" - }, - { - "vid": 102, - "name": "Data VLAN", - "status": "active" - } - ] - } - } - ], - "id": "67cc662a-4598-4fb2-a39c-788344fb0e55", - "sdk_name": "diode-sdk-python-dry-run", - "sdk_version": "0.0.0" - }, - { - "stream": "latest", - "entities": [ - { - "timestamp": "2025-06-13T13:05:00.416909Z", - "interface": { - "name": "VirtualGigabitEthernet1/0/1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "parent": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Port-Channel1", - "type": "1000base-t" - }, - "module": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - }, - "module_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S-MODULE" - } - }, - "label": "Core Link 1", - "type": "virtual", - "enabled": true, - "bridge": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Bridge1", - "type": "bridge" - }, - "mtu": "9000", - "primary_mac_address": { - "mac_address": "00:11:22:33:44:55" - }, - "speed": "1000000000", - "duplex": "full", - "wwn": "50:01:43:80:00:00:00:00", - "vrf": { - "name": "PROD-VRF" - }, - "description": "Core network interface", - "mode": "q-in-q", - "mark_connected": false, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ], - "mgmt_only": false, - "untagged_vlan": { - "vid": 444, - "name": "Data VLAN", - "status": "active" - }, - "qinq_svlan": { - "vid": 2000, - "name": "Service VLAN", - "status": "active" - }, - "vlan_translation_policy": { - "name": "Customer Translation Policy", - "description": "VLAN translation for customer traffic" - }, - "vdcs": [ - { - "name": "VDC1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "identifier": 1, - "status": "active", - "description": "Primary VDC" - } - ], - "tagged_vlans": [ - { - "vid": 101, - "name": "Voice VLAN", - "status": "active" - }, - { - "vid": 102, - "name": "Data VLAN", - "status": "active" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:00.416909Z", - "inventory_item": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "parent": { - "name": "Chassis 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - }, - "name": "Power Supply 1", - "label": "PSU1", - "role": { - "name": "Power Supply", - "color": "00ff00" - }, - "manufacturer": { - "name": "Cisco" - }, - "part_id": "PWR-C1-715WAC", - "serial": "ABC123XYZ", - "asset_tag": "ASSET-001", - "discovered": true, - "description": "715W AC Power Supply", - "status": "active", - "component_power_port": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "PSU1 Power Port", - "type": "iec-60320-c14", - "maximum_draw": 715, - "allocated_draw": 500, - "description": "Power input port for PSU1" - }, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:00.416909Z", - "inventory_item_role": { - "name": "Line Card", - "slug": "line-card", - "color": "0000ff", - "description": "Network switch line card module", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:00.416909Z", - "l2vpn": { - "name": "Customer-VPLS-1", - "slug": "customer-vpls-1", - "type": "vpls", - "identifier": "65000", - "import_targets": [ - { - "name": "65000:1001", - "description": "Primary import target" - }, - { - "name": "65000:1002", - "description": "Secondary import target" - } - ], - "export_targets": [ - { - "name": "65000:1003", - "description": "Primary export target" - } - ], - "description": "Customer VPLS service for multi-site connectivity", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:00.416909Z", - "l2vpn_termination": { - "l2vpn": { - "name": "Customer-VPLS-1", - "type": "vpls", - "identifier": "65000" - }, - "assigned_object_interface": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "GigabitEthernet1/0/1", - "type": "1000base-t", - "enabled": true - }, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:00.416909Z", - "location": { - "name": "Data Center East Wing", - "slug": "dc-east-wing", - "site": { - "name": "Site 1" - }, - "parent": { - "name": "Main Data Center", - "slug": "main-dc", - "site": { - "name": "Site 1" - } - }, - "status": "active", - "tenant": { - "name": "Tenant 1" - }, - "facility": "Building A, Floor 3", - "description": "East wing of the main data center facility", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:00.416909Z", - "mac_address": { - "mac_address": "00:1A:2B:3C:4D:5E", - "assigned_object_interface": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "GigabitEthernet1/0/1", - "type": "1000base-t", - "enabled": true - }, - "description": "Primary management interface MAC", - "comments": "Reserved for network management access", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:00.416909Z", - "manufacturer": { - "name": "Arista Networks", - "slug": "arista-networks", - "description": "Leading provider of cloud networking solutions", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:00.416909Z", - "module": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - }, - "module_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S-STACK" - }, - "status": "active", - "serial": "MOD123XYZ", - "asset_tag": "MOD-001", - "description": "Stacking module for switch interconnect", - "comments": "Primary stack member module", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:00.416909Z", - "module_bay": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Stack Module Bay 2", - "module": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S-STACK" - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - } - }, - "label": "STACK-2", - "position": "Rear", - "description": "Secondary stacking module bay", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - } - ], - "id": "5a0eb383-c2b5-439b-be75-444c547a3d9e", - "sdk_name": "diode-sdk-python-dry-run", - "sdk_version": "0.0.0" - }, - { - "stream": "latest", - "entities": [ - { - "timestamp": "2025-06-13T13:05:01.416909Z", - "module_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C9300-NM-8X", - "part_number": "C9300-NM-8X=", - "airflow": "front-to-rear", - "weight": 0.7, - "weight_unit": "kg", - "description": "Catalyst 9300 8 x 10GE Network Module", - "comments": "Hot-swappable uplink module for C9300 series switches", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:01.416909Z", - "platform": { - "name": "Cisco IOS-XE", - "slug": "cisco-ios-xe", - "manufacturer": { - "name": "Cisco" - }, - "description": "Enterprise-class IOS operating system for Catalyst switches and ISR routers", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:01.416909Z", - "power_feed": { - "power_panel": { - "site": { - "name": "Site 1" - }, - "name": "Panel A" - }, - "rack": { - "name": "Rack 1", - "site": { - "name": "Site 1" - } - }, - "name": "Power Feed A1", - "status": "active", - "type": "primary", - "supply": "ac", - "phase": "three-phase", - "voltage": "208", - "amperage": "30", - "max_utilization": "80", - "mark_connected": true, - "description": "Primary power feed for network equipment rack", - "tenant": { - "name": "Tenant 1" - }, - "comments": "Connected to UPS system A with redundant backup", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:01.416909Z", - "power_outlet": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "PWR-C1-715WAC" - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - } - }, - "name": "PSU1-Outlet1", - "label": "OUT-1", - "type": "iec-60320-c13", - "color": "0000ff", - "power_port": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "PSU1" - }, - "feed_leg": "A", - "description": "Power outlet for network switch PSU", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:01.416909Z", - "power_panel": { - "site": { - "name": "Site 1" - }, - "location": { - "name": "Data Center East Wing", - "slug": "dc-east-wing", - "site": { - "name": "Site 1" - } - }, - "name": "Panel B", - "description": "Secondary power distribution panel for network equipment", - "comments": "Connected to redundant UPS system with automatic transfer switch", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:01.416909Z", - "power_port": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "PWR-C1-715WAC" - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - } - }, - "name": "PSU2", - "label": "PWR-2", - "type": "iec-60320-c14", - "maximum_draw": "715", - "allocated_draw": "650", - "description": "Secondary power supply unit input", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:01.416909Z", - "prefix": { - "prefix": "10.100.0.0/16", - "vrf": { - "name": "PROD-VRF", - "rd": "65000:1" - }, - "scope_site": { - "name": "Site 1" - }, - "tenant": { - "name": "Tenant 1" - }, - "vlan": { - "name": "Production VLAN", - "vid": "112" - }, - "status": "active", - "role": { - "name": "Production", - "slug": "production" - }, - "is_pool": true, - "mark_utilized": true, - "description": "Production network address space", - "comments": "Primary address allocation for production services", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:01.416909Z", - "provider": { - "name": "Level 3 Communications", - "slug": "level3", - "description": "Global Tier 1 Internet Service Provider", - "comments": "Primary transit provider for data center connectivity", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ], - "accounts": [ - { - "provider": { - "name": "Level 3 Communications" - }, - "name": "East Coast Account", - "account": "L3-12345", - "description": "East Coast regional services account", - "comments": "Managed through regional NOC" - }, - { - "provider": { - "name": "Level 3 Communications" - }, - "name": "West Coast Account", - "account": "L3-67890", - "description": "West Coast regional services account", - "comments": "Managed through regional NOC" - } - ], - "asns": [ - { - "asn": "3356", - "rir": { - "name": "ARIN" - }, - "tenant": { - "name": "Tenant 1" - }, - "description": "Level 3 Global ASN", - "comments": "Primary transit ASN" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:01.416909Z", - "provider_account": { - "provider": { - "name": "AT&T" - }, - "name": "Global Enterprise Services", - "account": "ATT-GES-123456", - "description": "Global enterprise services and solutions account", - "comments": "Primary account for worldwide MPLS and managed services", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:01.416909Z", - "provider_network": { - "provider": { - "name": "Level 3 Communications" - }, - "name": "Global MPLS Network", - "service_id": "L3-MPLS-001", - "description": "Global MPLS backbone network", - "comments": "Primary enterprise MPLS network infrastructure", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - } - ], - "id": "479f1a4c-9503-448c-a9f8-63d759b5ad0b", - "sdk_name": "diode-sdk-python-dry-run", - "sdk_version": "0.0.0" - }, - { - "stream": "latest", - "entities": [ - { - "timestamp": "2025-06-13T13:05:02.416909Z", - "rir": { - "name": "ARIN", - "slug": "arin", - "is_private": false, - "description": "American Registry for Internet Numbers", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:02.416909Z", - "rack": { - "name": "Rack 1", - "facility_id": "FAC-001", - "site": { - "name": "Site 1" - }, - "location": { - "name": "Data Center East Wing", - "site": { - "name": "Site 1" - } - }, - "tenant": { - "name": "Tenant 1" - }, - "status": "active", - "role": { - "name": "Server Rack", - "slug": "server-rack", - "color": "0000ff", - "description": "Primary server rack role" - }, - "serial": "RACK123XYZ", - "asset_tag": "RACK-001", - "rack_type": { - "manufacturer": { - "name": "Manufacturer 1" - }, - "model": "R2000", - "slug": "r2000", - "form_factor": "4-post-cabinet" - }, - "form_factor": "4-post-cabinet", - "width": "19", - "u_height": "42", - "starting_unit": "1", - "weight": "350.5", - "max_weight": "1000", - "weight_unit": "lb", - "desc_units": false, - "outer_width": "24", - "outer_depth": "36", - "outer_unit": "in", - "mounting_depth": "30", - "airflow": "front-to-rear", - "description": "Standard 42U server rack", - "comments": "Located in primary data center", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:02.416909Z", - "rack_reservation": { - "rack": { - "name": "Rack 1", - "site": { - "name": "Site 1" - } - }, - "units": [ - "1", - "2", - "3", - "4" - ], - "tenant": { - "name": "Tenant 1" - }, - "description": "Reserved for new server deployment", - "comments": "Project XYZ equipment installation", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:02.416909Z", - "rack_role": { - "name": "Network Equipment", - "slug": "network-equipment", - "color": "0000ff", - "description": "Dedicated racks for network infrastructure", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:02.416909Z", - "rack_type": { - "manufacturer": { - "name": "Manufacturer 1" - }, - "model": "R2000", - "slug": "r2000", - "description": "Standard 42U server rack", - "form_factor": "4-post-cabinet", - "width": "19", - "u_height": "42", - "starting_unit": "1", - "desc_units": false, - "outer_width": "24", - "outer_depth": "36", - "outer_unit": "in", - "weight": 350.5, - "max_weight": "1000", - "weight_unit": "lb", - "mounting_depth": "30", - "comments": "Standard enterprise rack configuration", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:02.416909Z", - "rear_port": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module": { - "asset_tag": "module-1234567890", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "module_bay": { - "name": "Module Bay 1", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - } - }, - "module_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S-MODULE" - } - }, - "name": "Rear Port 1", - "label": "RP1", - "type": "lc-apc", - "color": "ff00ff", - "positions": "1", - "description": "Rear fiber port", - "mark_connected": true, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:02.416909Z", - "region": { - "name": "North America", - "slug": "north-america", - "parent": { - "name": "Global", - "slug": "global", - "description": "Global Region", - "tags": [ - { - "name": "Tag 1" - } - ] - }, - "description": "North American Region", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:02.416909Z", - "role": { - "name": "Network Administrator", - "slug": "network-admin", - "weight": "1000", - "description": "Primary network administration role", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:02.416909Z", - "route_target": { - "name": "65000:3001", - "tenant": { - "name": "Tenant 1" - }, - "description": "Primary route target for MPLS VPN", - "comments": "Used for customer VPN service", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:02.416909Z", - "service": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Web Server", - "protocol": "tcp", - "ports": [ - "80", - "443" - ], - "description": "Primary web server service", - "comments": "Handles HTTPS traffic for main website", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ], - "ipaddresses": [ - { - "address": "192.168.1.100/24", - "status": "active", - "dns_name": "web.example.com" - } - ] - } - } - ], - "id": "ba68d239-8d88-4350-9692-16020ab14b9f", - "sdk_name": "diode-sdk-python-dry-run", - "sdk_version": "0.0.0" - }, - { - "stream": "latest", - "entities": [ - { - "timestamp": "2025-06-13T13:05:03.416909Z", - "site": { - "name": "Data Center West", - "slug": "dc-west", - "status": "active", - "region": { - "name": "North America", - "slug": "north-america" - }, - "group": { - "name": "Primary Data Centers", - "slug": "primary-dcs" - }, - "tenant": { - "name": "Tenant 1" - }, - "facility": "Building 7", - "time_zone": "America/Los_Angeles", - "description": "Primary West Coast Data Center", - "physical_address": "123 Tech Drive, San Jose, CA 95134", - "shipping_address": "Receiving Dock 3, 123 Tech Drive, San Jose, CA 95134", - "latitude": 37.3382, - "longitude": -121.8863, - "comments": "24x7 access requires security clearance", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ], - "asns": [ - { - "asn": "555", - "rir": { - "name": "RIR 1" - }, - "tenant": { - "name": "Tenant 1" - }, - "description": "ASN 555 Description", - "comments": "ASN 555 Comments", - "tags": [ - { - "name": "Tag 1" - } - ] - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:03.416909Z", - "site_group": { - "name": "Global Data Centers", - "slug": "global-dcs", - "parent": { - "name": "Infrastructure", - "slug": "infrastructure" - }, - "description": "Worldwide data center facilities", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:03.416909Z", - "tag": { - "name": "Production", - "slug": "production", - "color": "ff0000" - } - }, - { - "timestamp": "2025-06-13T13:05:03.416909Z", - "tenant": { - "name": "Acme Corporation", - "slug": "acme-corp", - "group": { - "name": "Enterprise Customers", - "slug": "enterprise-customers" - }, - "description": "Global technology solutions provider", - "comments": "Fortune 500 company with worldwide operations", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:03.416909Z", - "tenant_group": { - "name": "Financial Services", - "slug": "financial-services", - "parent": { - "name": "Enterprise Sectors", - "slug": "enterprise-sectors" - }, - "description": "Banking and financial industry customers", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:03.416909Z", - "tunnel": { - "name": "DC-West-to-East-Primary", - "status": "active", - "group": { - "name": "Inter-DC Tunnels", - "slug": "inter-dc-tunnels" - }, - "encapsulation": "ipsec-tunnel", - "ipsec_profile": { - "name": "IPSEC-PROFILE-1", - "mode": "esp", - "ike_policy": { - "name": "IKE-POLICY-TUN-1", - "version": "2", - "preshared_key": "1234567890", - "comments": "Using AES-256-GCM encryption with PFS" - }, - "ipsec_policy": { - "name": "IPSEC-POLICY-1", - "pfs_group": "2" - } - }, - "tenant": { - "name": "Tenant 1" - }, - "tunnel_id": "1001", - "description": "Primary IPSec tunnel between West and East data centers", - "comments": "Using AES-256-GCM encryption with PFS", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:03.416909Z", - "tunnel_group": { - "name": "Regional Backbones", - "slug": "regional-backbones", - "description": "High-capacity encrypted tunnels between regional data centers", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:03.416909Z", - "tunnel_termination": { - "tunnel": { - "name": "DC-West-to-East-Primary", - "status": "active", - "encapsulation": "ipsec-tunnel" - }, - "role": "hub", - "termination_device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "outside_ip": { - "address": "203.0.113.1/24", - "status": "active", - "dns_name": "vpn1.example.com" - }, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:03.416909Z", - "vlan": { - "group": { - "name": "Production VLANs", - "slug": "production-vlans" - }, - "vid": "807", - "name": "Production Servers", - "tenant": { - "name": "Tenant 1" - }, - "status": "active", - "role": { - "name": "Production", - "slug": "production" - }, - "description": "Primary production server network", - "qinq_role": "cvlan", - "qinq_svlan": { - "vid": "1909", - "name": "Service Provider VLAN" - }, - "comments": "Used for customer-facing production workloads", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:03.416909Z", - "vlan_group": { - "name": "Data Center Core", - "slug": "dc-core", - "scope_site": { - "name": "Data Center West", - "slug": "dc-west", - "status": "active" - }, - "description": "Core network VLANs for data center infrastructure", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - } - ], - "id": "287f8602-868b-41d4-92fe-47bb9fc84fbb", - "sdk_name": "diode-sdk-python-dry-run", - "sdk_version": "0.0.0" - }, - { - "stream": "latest", - "entities": [ - { - "timestamp": "2025-06-13T13:05:04.416909Z", - "vlan_translation_policy": { - "name": "Customer Edge Translation", - "description": "VLAN translation policy for customer edge interfaces" - } - }, - { - "timestamp": "2025-06-13T13:05:04.416909Z", - "vlan_translation_rule": { - "policy": { - "name": "Customer Edge Translation", - "description": "VLAN translation policy for customer edge interfaces" - }, - "local_vid": "100", - "remote_vid": "1100", - "description": "Map customer VLAN 100 to provider VLAN 1100" - } - }, - { - "timestamp": "2025-06-13T13:05:04.416909Z", - "vm_interface": { - "virtual_machine": { - "name": "web-server-01", - "status": "active", - "role": { - "name": "Web Server" - }, - "site": { - "name": "Site 1" - } - }, - "name": "eth0", - "enabled": true, - "parent": { - "virtual_machine": { - "name": "web-server-01", - "status": "active", - "role": { - "name": "Web Server" - }, - "site": { - "name": "Site 1" - } - }, - "name": "bond0" - }, - "bridge": { - "virtual_machine": { - "name": "web-server-01", - "status": "active", - "role": { - "name": "Web Server" - }, - "site": { - "name": "Site 1" - } - }, - "name": "br0" - }, - "mtu": "9000", - "primary_mac_address": { - "mac_address": "00:1A:2B:3C:4D:5E" - }, - "description": "Primary network interface", - "mode": "q-in-q", - "untagged_vlan": { - "vid": "1101", - "name": "Production Servers" - }, - "qinq_svlan": { - "vid": "1000", - "name": "Service Provider VLAN" - }, - "vlan_translation_policy": { - "name": "Customer Edge Translation" - }, - "vrf": { - "name": "PROD-VRF", - "rd": "65000:1" - }, - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:04.416909Z", - "vrf": { - "name": "Customer-A-VRF", - "rd": "65000:100", - "tenant": { - "name": "Tenant 1" - }, - "enforce_unique": true, - "description": "Isolated routing domain for Customer A", - "comments": "Used for customer's private network services", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ], - "import_targets": [ - { - "name": "65000:100" - }, - { - "name": "65000:101" - } - ], - "export_targets": [ - { - "name": "65000:103" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:04.416909Z", - "virtual_chassis": { - "name": "Stack-DC1-Core", - "domain": "dc1-core.example.com", - "master": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "description": "Core switch stack in DC1", - "comments": "Primary switching infrastructure for data center 1", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:04.416909Z", - "virtual_circuit": { - "cid": "VC-001-LAX-NYC", - "provider_network": { - "provider": { - "name": "Level 3 Communications" - }, - "name": "Global MPLS Network", - "service_id": "L3-MPLS-001" - }, - "provider_account": { - "provider": { - "name": "Level 3 Communications" - }, - "name": "East Coast Account", - "account": "L3-12345" - }, - "type": { - "name": "MPLS L3VPN", - "slug": "mpls-l3vpn" - }, - "status": "active", - "tenant": { - "name": "Tenant 1" - }, - "description": "LAX to NYC MPLS circuit", - "comments": "Primary east-west connectivity", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:04.416909Z", - "virtual_circuit_termination": { - "virtual_circuit": { - "cid": "VC-001-LAX-NYC", - "provider_network": { - "provider": { - "name": "Level 3 Communications" - }, - "name": "Global MPLS Network" - }, - "type": { - "name": "MPLS L3VPN", - "slug": "mpls-l3vpn" - } - }, - "role": "hub", - "interface": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "MegabitEthernet1/0/1", - "type": "virtual", - "enabled": true - }, - "description": "LAX hub termination for east-west MPLS circuit", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:04.416909Z", - "virtual_circuit_type": { - "name": "EVPN-VXLAN", - "slug": "evpn-vxlan", - "color": "0000ff", - "description": "Data center interconnect using EVPN-VXLAN overlay", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:04.416909Z", - "virtual_device_context": { - "name": "VDC-Production", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "identifier": "1", - "tenant": { - "name": "Tenant 1" - }, - "primary_ip4": { - "address": "192.168.1.1", - "assigned_object_interface": { - "type": "1000base-t", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "eth0" - } - }, - "primary_ip6": { - "address": "2001:db8::1", - "assigned_object_interface": { - "type": "1000base-t", - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "eth0" - } - }, - "status": "active", - "description": "Production virtual device context", - "comments": "Isolated network context for production services", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:04.416909Z", - "virtual_disk": { - "virtual_machine": { - "name": "web-server-01", - "status": "active", - "role": { - "name": "Web Server" - }, - "site": { - "name": "Site 1" - } - }, - "name": "root-volume", - "description": "Primary system disk", - "size": "182400", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - } - ], - "id": "f1faa85b-e0a9-4c20-9134-1c86f14f663b", - "sdk_name": "diode-sdk-python-dry-run", - "sdk_version": "0.0.0" - }, - { - "stream": "latest", - "entities": [ - { - "timestamp": "2025-06-13T13:05:05.416909Z", - "virtual_machine": { - "name": "app-server-01", - "status": "active", - "site": { - "name": "Site 1" - }, - "cluster": { - "name": "Cluster 1", - "type": { - "name": "Cluster Type 1" - }, - "scope_site": { - "name": "Site 1" - } - }, - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - }, - "cluster": { - "name": "Cluster 1", - "type": { - "name": "Cluster Type 1" - }, - "scope_site": { - "name": "Site 1" - } - } - }, - "serial": "VM-2023-001", - "role": { - "name": "Application Server" - }, - "tenant": { - "name": "Tenant 1" - }, - "platform": { - "name": "Ubuntu 22.04" - }, - "primary_ip4": { - "address": "192.168.2.99", - "assigned_object_vm_interface": { - "virtual_machine": { - "name": "app-server-01", - "cluster": { - "name": "Cluster 1", - "type": { - "name": "Cluster Type 1" - }, - "scope_site": { - "name": "Site 1" - } - }, - "tenant": { - "name": "Tenant 1" - } - }, - "name": "eth0", - "enabled": true, - "mtu": "1500" - } - }, - "primary_ip6": { - "address": "2001:db8::99", - "assigned_object_vm_interface": { - "virtual_machine": { - "name": "app-server-01", - "cluster": { - "name": "Cluster 1", - "type": { - "name": "Cluster Type 1" - }, - "scope_site": { - "name": "Site 1" - } - }, - "tenant": { - "name": "Tenant 1" - } - }, - "name": "eth0", - "enabled": true, - "mtu": "1500" - } - }, - "vcpus": 4.0, - "memory": "214748364", - "disk": "147483647", - "description": "Primary application server instance", - "comments": "Hosts critical business applications", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:05.416909Z", - "wireless_lan": { - "ssid": "Corp-Secure", - "description": "Corporate secure wireless network", - "group": { - "name": "Corporate Networks", - "slug": "corporate-networks" - }, - "status": "active", - "vlan": { - "vid": 100, - "name": "Production Servers" - }, - "scope_site": { - "name": "Site 1" - }, - "tenant": { - "name": "Tenant 1" - }, - "auth_type": "wpa-enterprise", - "auth_cipher": "aes", - "auth_psk": "SecureWiFiKey123!", - "comments": "Primary corporate wireless network with 802.1X authentication", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:05.416909Z", - "wireless_lan_group": { - "name": "Corporate Networks", - "slug": "corporate-networks", - "parent": { - "name": "All Networks", - "slug": "all-networks" - }, - "description": "Enterprise corporate wireless networks", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - }, - { - "timestamp": "2025-06-13T13:05:05.416909Z", - "wireless_link": { - "interface_a": { - "device": { - "name": "Device 1", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Radio0/1", - "type": "ieee802.11ac", - "enabled": true - }, - "interface_b": { - "device": { - "name": "Device 2", - "role": { - "name": "Device Role 1" - }, - "device_type": { - "manufacturer": { - "name": "Cisco" - }, - "model": "C2960S" - }, - "site": { - "name": "Site 1" - } - }, - "name": "Radio0/1", - "type": "ieee802.11ac", - "enabled": true - }, - "ssid": "P2P-Link-1", - "status": "connected", - "tenant": { - "name": "Tenant 1" - }, - "auth_type": "wpa-personal", - "auth_cipher": "aes", - "auth_psk": "P2PLinkKey123!", - "distance": 1.5, - "distance_unit": "km", - "description": "Point-to-point wireless backhaul link", - "comments": "Building A to Building B wireless bridge", - "tags": [ - { - "name": "Tag 1" - }, - { - "name": "Tag 2" - } - ] - } - } - ], - "id": "2f100ecf-9b81-45e6-bd36-d37e7761db91", - "sdk_name": "diode-sdk-python-dry-run", - "sdk_version": "0.0.0" - } -] \ No newline at end of file diff --git a/tests/test_client.py b/tests/test_client.py index d8dba52..d2178d4 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -516,9 +516,9 @@ def continuation(x, _): @pytest.fixture -def messages_path() -> Path: - """Path to the bundled dry-run messages.""" - return Path(__file__).resolve().parent / "fixtures" / "messages.json" +def message_path() -> Path: + """Path to the bundled dry-run message.""" + return Path(__file__).resolve().parent / "fixtures" / "message.json" @pytest.fixture @@ -688,27 +688,31 @@ def test_ingest_dry_run_stdout(capsys): def test_ingest_dry_run_file(tmp_path): """Verify ingest writes JSON to file when dry run output file is set.""" - output_file = tmp_path / "out.json" client = DiodeDryRunClient( - dry_run_output_file=str(output_file), + app_name="agent/my-producer", + output_dir=str(tmp_path), ) client._stub = MagicMock() client.ingest(entities=[Entity(site="Site1"), Entity(device="Device1")]) client.ingest(entities=[Entity(site="Site2"), Entity(device="Device2")]) + files = list(tmp_path.glob("agent_my-producer*.json")) + assert len(files) == 2 assert client._stub.Ingest.call_count == 0 - assert output_file.read_text().startswith("[") + for f in files: + assert f.read_text().startswith("{") def test_load_dryrun_entities(tmp_path): """Verify ``load_dryrun_entities`` yields protobuf entities.""" - output_file = tmp_path / "dryrun.jsonl" - client = DiodeDryRunClient(dry_run_output_file=str(output_file)) + client = DiodeDryRunClient(output_dir=str(tmp_path)) client.ingest(entities=[Entity(site="Site1"), Entity(device="Device1")]) - entities = list(load_dryrun_entities(output_file)) + files = list(tmp_path.glob("dryrun*.json")) + assert len(files) == 1 + entities = list(load_dryrun_entities(files[0])) assert len(entities) == 2 assert isinstance(entities[0], ingester_pb2.Entity) @@ -717,9 +721,9 @@ def test_load_dryrun_entities(tmp_path): assert entities[1].device.name == "Device1" -def test_load_dryrun_entities_from_fixture(messages_path, tmp_path): +def test_load_dryrun_entities_from_fixture(message_path, tmp_path): """Ensure entities load correctly from the bundled fixture.""" - entities = list(load_dryrun_entities(messages_path)) + entities = list(load_dryrun_entities(message_path)) assert len(entities) == 94 assert isinstance(entities[0], ingester_pb2.Entity) @@ -730,17 +734,18 @@ def test_load_dryrun_entities_from_fixture(messages_path, tmp_path): ) assert entities[-1].wireless_link.ssid == "P2P-Link-1" - output_file = tmp_path / "out.json" - client = DiodeDryRunClient( - dry_run_output_file=str(output_file), - ) + client = DiodeDryRunClient(output_dir=str(tmp_path)) client._stub = MagicMock() client.ingest(entities=entities) + assert client._stub.Ingest.call_count == 0 - assert output_file.read_text().startswith("[") + files = list(tmp_path.glob("dryrun*.json")) + assert len(files) == 1 + entities = list(load_dryrun_entities(files[0])) + assert files[0].read_text().startswith("{") - entities = list(load_dryrun_entities(output_file)) + entities = list(load_dryrun_entities(files[0])) assert len(entities) == 94 assert isinstance(entities[0], ingester_pb2.Entity) From 6240b332c52bc0e2d34a7fd47d00e4d27f9782fe Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Mon, 16 Jun 2025 16:52:14 -0300 Subject: [PATCH 17/18] Improve docs --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 4d95f5a..3cfab7b 100644 --- a/README.md +++ b/README.md @@ -78,9 +78,7 @@ if __name__ == "__main__": ### Dry run mode -`DiodeDryRunClient` allows generating ingestion requests without contacting a -Diode server. Each request is printed to stdout or written to a JSON Lines file -when `output_dir` (or `DIODE_DRY_RUN_OUTPUT_FILE`) is set. +`DiodeDryRunClient` generates ingestion requests without contacting a Diode server. Requests are printed to stdout by default, or written to JSON files when `output_dir` (or the `DIODE_DRY_RUN_OUTPUT_DIR` environment variable) is specified. The `app_name` parameter serves as the filename prefix; if not provided, `dryrun` is used as the default prefix. ```python from netboxlabs.diode.sdk import DiodeDryRunClient From 53c51a249bd49bbeccb0ccc6d28b4ff948f5abfd Mon Sep 17 00:00:00 2001 From: Leonardo Parente <23251360+leoparente@users.noreply.github.com> Date: Tue, 17 Jun 2025 10:37:54 -0300 Subject: [PATCH 18/18] Add missing info readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3cfab7b..690040c 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ if __name__ == "__main__": ### Dry run mode -`DiodeDryRunClient` generates ingestion requests without contacting a Diode server. Requests are printed to stdout by default, or written to JSON files when `output_dir` (or the `DIODE_DRY_RUN_OUTPUT_DIR` environment variable) is specified. The `app_name` parameter serves as the filename prefix; if not provided, `dryrun` is used as the default prefix. +`DiodeDryRunClient` generates ingestion requests without contacting a Diode server. Requests are printed to stdout by default, or written to JSON files when `output_dir` (or the `DIODE_DRY_RUN_OUTPUT_DIR` environment variable) is specified. The `app_name` parameter serves as the filename prefix; if not provided, `dryrun` is used as the default prefix. The file name is suffixed with a nanosecond-precision timestamp, resulting in the format `_.json`. ```python from netboxlabs.diode.sdk import DiodeDryRunClient