From 00a9283e32804924a252ea92707b47a50ff85ec3 Mon Sep 17 00:00:00 2001 From: Ben Thomasson Date: Fri, 16 Mar 2018 11:21:08 -0400 Subject: [PATCH] Adds an API for network UI, action plugins, and API client * Adds a simple DRF API for network-ui * Moves network_ui api to v1_api * Uses BaseSerializer for networking v1 api * Adds v2 of the network API * Uses standard AWX base classes for the network UI API * Adds canvas prefix to network UI api URL names * Adds ansible action plugins for automating network UI workflows * Adds python client for the networking visualization API --- awx/network_ui/Makefile | 111 +++- .../action_plugins/create_device.py | 61 ++ awx/network_ui/action_plugins/create_group.py | 58 ++ .../action_plugins/create_groupdevice.py | 46 ++ .../action_plugins/create_interface.py | 48 ++ awx/network_ui/action_plugins/create_link.py | 54 ++ .../action_plugins/create_process.py | 51 ++ .../action_plugins/create_stream.py | 51 ++ .../action_plugins/create_toolbox.py | 44 ++ .../action_plugins/create_toolboxitem.py | 46 ++ .../action_plugins/create_topology.py | 59 ++ .../create_topologyinventory.py | 46 ++ .../action_plugins/delete_device.py | 29 + awx/network_ui/action_plugins/delete_group.py | 29 + .../action_plugins/delete_groupdevice.py | 29 + .../action_plugins/delete_interface.py | 29 + awx/network_ui/action_plugins/delete_link.py | 29 + .../action_plugins/delete_process.py | 29 + .../action_plugins/delete_stream.py | 29 + .../action_plugins/delete_toolbox.py | 29 + .../action_plugins/delete_toolboxitem.py | 29 + .../action_plugins/delete_topology.py | 29 + .../delete_topologyinventory.py | 29 + awx/network_ui/action_plugins/get_device.py | 32 + awx/network_ui/action_plugins/get_group.py | 32 + .../action_plugins/get_groupdevice.py | 32 + .../action_plugins/get_interface.py | 32 + awx/network_ui/action_plugins/get_link.py | 32 + awx/network_ui/action_plugins/get_process.py | 32 + awx/network_ui/action_plugins/get_stream.py | 32 + awx/network_ui/action_plugins/get_toolbox.py | 32 + .../action_plugins/get_toolboxitem.py | 32 + awx/network_ui/action_plugins/get_topology.py | 32 + .../action_plugins/get_topologyinventory.py | 32 + awx/network_ui/action_plugins/list_device.py | 57 ++ awx/network_ui/action_plugins/list_group.py | 55 ++ .../action_plugins/list_groupdevice.py | 43 ++ .../action_plugins/list_interface.py | 45 ++ awx/network_ui/action_plugins/list_link.py | 51 ++ awx/network_ui/action_plugins/list_process.py | 47 ++ awx/network_ui/action_plugins/list_stream.py | 47 ++ awx/network_ui/action_plugins/list_toolbox.py | 41 ++ .../action_plugins/list_toolboxitem.py | 43 ++ .../action_plugins/list_topology.py | 55 ++ .../action_plugins/list_topologyinventory.py | 43 ++ .../action_plugins/update_device.py | 56 ++ awx/network_ui/action_plugins/update_group.py | 54 ++ .../action_plugins/update_groupdevice.py | 42 ++ .../action_plugins/update_interface.py | 44 ++ awx/network_ui/action_plugins/update_link.py | 50 ++ .../action_plugins/update_process.py | 46 ++ .../action_plugins/update_stream.py | 46 ++ .../action_plugins/update_toolbox.py | 40 ++ .../action_plugins/update_toolboxitem.py | 42 ++ .../action_plugins/update_topology.py | 54 ++ .../update_topologyinventory.py | 42 ++ awx/network_ui/admin.py | 2 +- awx/network_ui/client/README.md | 3 + awx/network_ui/client/conf.py | 11 + .../client/networking_visualization_client.py | 94 +++ awx/network_ui/client/requirements.txt | 3 + awx/network_ui/client/util.py | 27 + awx/network_ui/client/v1_api_client.py | 586 +++++++++++++++++ awx/network_ui/client/v2_api_client.py | 500 +++++++++++++++ awx/network_ui/designs/api.yml | 66 ++ awx/network_ui/designs/merge_design.py | 49 ++ awx/network_ui/designs/models.yml | 89 ++- awx/network_ui/designs/new.yml | 526 +++++++++++++++ awx/network_ui/library/create_device.py | 1 + awx/network_ui/library/create_group.py | 1 + awx/network_ui/library/create_groupdevice.py | 1 + awx/network_ui/library/create_interface.py | 1 + awx/network_ui/library/create_link.py | 1 + awx/network_ui/library/create_process.py | 1 + awx/network_ui/library/create_stream.py | 1 + awx/network_ui/library/create_toolbox.py | 1 + awx/network_ui/library/create_toolboxitem.py | 1 + awx/network_ui/library/create_topology.py | 1 + .../library/create_topologyinventory.py | 1 + awx/network_ui/library/delete_device.py | 1 + awx/network_ui/library/delete_group.py | 1 + awx/network_ui/library/delete_groupdevice.py | 1 + awx/network_ui/library/delete_interface.py | 1 + awx/network_ui/library/delete_link.py | 1 + awx/network_ui/library/delete_process.py | 1 + awx/network_ui/library/delete_stream.py | 1 + awx/network_ui/library/delete_toolbox.py | 1 + awx/network_ui/library/delete_toolboxitem.py | 1 + awx/network_ui/library/delete_topology.py | 1 + .../library/delete_topologyinventory.py | 1 + awx/network_ui/library/get_device.py | 1 + awx/network_ui/library/get_group.py | 1 + awx/network_ui/library/get_groupdevice.py | 1 + awx/network_ui/library/get_interface.py | 1 + awx/network_ui/library/get_link.py | 1 + awx/network_ui/library/get_process.py | 1 + awx/network_ui/library/get_stream.py | 1 + awx/network_ui/library/get_toolbox.py | 1 + awx/network_ui/library/get_toolboxitem.py | 1 + awx/network_ui/library/get_topology.py | 1 + .../library/get_topologyinventory.py | 1 + awx/network_ui/library/list_device.py | 1 + awx/network_ui/library/list_group.py | 1 + awx/network_ui/library/list_groupdevice.py | 1 + awx/network_ui/library/list_interface.py | 1 + awx/network_ui/library/list_link.py | 1 + awx/network_ui/library/list_process.py | 1 + awx/network_ui/library/list_stream.py | 1 + awx/network_ui/library/list_toolbox.py | 1 + awx/network_ui/library/list_toolboxitem.py | 1 + awx/network_ui/library/list_topology.py | 1 + .../library/list_topologyinventory.py | 1 + awx/network_ui/library/update_device.py | 1 + awx/network_ui/library/update_group.py | 1 + awx/network_ui/library/update_groupdevice.py | 1 + awx/network_ui/library/update_interface.py | 1 + awx/network_ui/library/update_link.py | 1 + awx/network_ui/library/update_process.py | 1 + awx/network_ui/library/update_stream.py | 1 + awx/network_ui/library/update_toolbox.py | 1 + awx/network_ui/library/update_toolboxitem.py | 1 + awx/network_ui/library/update_topology.py | 1 + .../library/update_topologyinventory.py | 1 + awx/network_ui/models.py | 2 +- .../templates/action_plugins/create_model.pyt | 51 ++ .../templates/action_plugins/delete_model.pyt | 35 + .../templates/action_plugins/get_model.pyt | 37 ++ .../templates/action_plugins/list_model.pyt | 45 ++ .../templates/action_plugins/update_model.pyt | 44 ++ .../templates/library/create_model.pyt | 5 + .../templates/library/delete_model.pyt | 5 + .../templates/library/get_model.pyt | 5 + .../templates/library/list_model.pyt | 5 + .../templates/library/update_model.pyt | 5 + awx/network_ui/templates/tuples.pyt | 10 + awx/network_ui/templates/v1_api_client.pyt | 50 ++ .../templates/v1_api_serializers.pyt | 15 + awx/network_ui/templates/v1_api_urls.pyt | 8 + awx/network_ui/templates/v1_api_views.pyt | 65 ++ awx/network_ui/templates/v2_api_access.pyt | 14 + awx/network_ui/templates/v2_api_client.pyt | 42 ++ .../templates/v2_api_serializers.pyt | 15 + awx/network_ui/templates/v2_api_urls.pyt | 18 + awx/network_ui/templates/v2_api_views.pyt | 72 +++ awx/network_ui/tuples.py | 179 ++++++ awx/network_ui/urls.py | 21 +- awx/network_ui/v1_api_serializers.py | 128 ++++ awx/network_ui/v1_api_urls.py | 18 + awx/network_ui/v1_api_views.py | 556 ++++++++++++++++ awx/network_ui/v2_api_access.py | 101 +++ awx/network_ui/v2_api_serializers.py | 128 ++++ awx/network_ui/v2_api_urls.py | 74 +++ awx/network_ui/v2_api_views.py | 598 ++++++++++++++++++ 153 files changed, 6729 insertions(+), 22 deletions(-) create mode 100644 awx/network_ui/action_plugins/create_device.py create mode 100644 awx/network_ui/action_plugins/create_group.py create mode 100644 awx/network_ui/action_plugins/create_groupdevice.py create mode 100644 awx/network_ui/action_plugins/create_interface.py create mode 100644 awx/network_ui/action_plugins/create_link.py create mode 100644 awx/network_ui/action_plugins/create_process.py create mode 100644 awx/network_ui/action_plugins/create_stream.py create mode 100644 awx/network_ui/action_plugins/create_toolbox.py create mode 100644 awx/network_ui/action_plugins/create_toolboxitem.py create mode 100644 awx/network_ui/action_plugins/create_topology.py create mode 100644 awx/network_ui/action_plugins/create_topologyinventory.py create mode 100644 awx/network_ui/action_plugins/delete_device.py create mode 100644 awx/network_ui/action_plugins/delete_group.py create mode 100644 awx/network_ui/action_plugins/delete_groupdevice.py create mode 100644 awx/network_ui/action_plugins/delete_interface.py create mode 100644 awx/network_ui/action_plugins/delete_link.py create mode 100644 awx/network_ui/action_plugins/delete_process.py create mode 100644 awx/network_ui/action_plugins/delete_stream.py create mode 100644 awx/network_ui/action_plugins/delete_toolbox.py create mode 100644 awx/network_ui/action_plugins/delete_toolboxitem.py create mode 100644 awx/network_ui/action_plugins/delete_topology.py create mode 100644 awx/network_ui/action_plugins/delete_topologyinventory.py create mode 100644 awx/network_ui/action_plugins/get_device.py create mode 100644 awx/network_ui/action_plugins/get_group.py create mode 100644 awx/network_ui/action_plugins/get_groupdevice.py create mode 100644 awx/network_ui/action_plugins/get_interface.py create mode 100644 awx/network_ui/action_plugins/get_link.py create mode 100644 awx/network_ui/action_plugins/get_process.py create mode 100644 awx/network_ui/action_plugins/get_stream.py create mode 100644 awx/network_ui/action_plugins/get_toolbox.py create mode 100644 awx/network_ui/action_plugins/get_toolboxitem.py create mode 100644 awx/network_ui/action_plugins/get_topology.py create mode 100644 awx/network_ui/action_plugins/get_topologyinventory.py create mode 100644 awx/network_ui/action_plugins/list_device.py create mode 100644 awx/network_ui/action_plugins/list_group.py create mode 100644 awx/network_ui/action_plugins/list_groupdevice.py create mode 100644 awx/network_ui/action_plugins/list_interface.py create mode 100644 awx/network_ui/action_plugins/list_link.py create mode 100644 awx/network_ui/action_plugins/list_process.py create mode 100644 awx/network_ui/action_plugins/list_stream.py create mode 100644 awx/network_ui/action_plugins/list_toolbox.py create mode 100644 awx/network_ui/action_plugins/list_toolboxitem.py create mode 100644 awx/network_ui/action_plugins/list_topology.py create mode 100644 awx/network_ui/action_plugins/list_topologyinventory.py create mode 100644 awx/network_ui/action_plugins/update_device.py create mode 100644 awx/network_ui/action_plugins/update_group.py create mode 100644 awx/network_ui/action_plugins/update_groupdevice.py create mode 100644 awx/network_ui/action_plugins/update_interface.py create mode 100644 awx/network_ui/action_plugins/update_link.py create mode 100644 awx/network_ui/action_plugins/update_process.py create mode 100644 awx/network_ui/action_plugins/update_stream.py create mode 100644 awx/network_ui/action_plugins/update_toolbox.py create mode 100644 awx/network_ui/action_plugins/update_toolboxitem.py create mode 100644 awx/network_ui/action_plugins/update_topology.py create mode 100644 awx/network_ui/action_plugins/update_topologyinventory.py create mode 100644 awx/network_ui/client/README.md create mode 100644 awx/network_ui/client/conf.py create mode 100755 awx/network_ui/client/networking_visualization_client.py create mode 100644 awx/network_ui/client/requirements.txt create mode 100644 awx/network_ui/client/util.py create mode 100644 awx/network_ui/client/v1_api_client.py create mode 100644 awx/network_ui/client/v2_api_client.py create mode 100644 awx/network_ui/designs/api.yml create mode 100755 awx/network_ui/designs/merge_design.py create mode 100644 awx/network_ui/designs/new.yml create mode 100644 awx/network_ui/library/create_device.py create mode 100644 awx/network_ui/library/create_group.py create mode 100644 awx/network_ui/library/create_groupdevice.py create mode 100644 awx/network_ui/library/create_interface.py create mode 100644 awx/network_ui/library/create_link.py create mode 100644 awx/network_ui/library/create_process.py create mode 100644 awx/network_ui/library/create_stream.py create mode 100644 awx/network_ui/library/create_toolbox.py create mode 100644 awx/network_ui/library/create_toolboxitem.py create mode 100644 awx/network_ui/library/create_topology.py create mode 100644 awx/network_ui/library/create_topologyinventory.py create mode 100644 awx/network_ui/library/delete_device.py create mode 100644 awx/network_ui/library/delete_group.py create mode 100644 awx/network_ui/library/delete_groupdevice.py create mode 100644 awx/network_ui/library/delete_interface.py create mode 100644 awx/network_ui/library/delete_link.py create mode 100644 awx/network_ui/library/delete_process.py create mode 100644 awx/network_ui/library/delete_stream.py create mode 100644 awx/network_ui/library/delete_toolbox.py create mode 100644 awx/network_ui/library/delete_toolboxitem.py create mode 100644 awx/network_ui/library/delete_topology.py create mode 100644 awx/network_ui/library/delete_topologyinventory.py create mode 100644 awx/network_ui/library/get_device.py create mode 100644 awx/network_ui/library/get_group.py create mode 100644 awx/network_ui/library/get_groupdevice.py create mode 100644 awx/network_ui/library/get_interface.py create mode 100644 awx/network_ui/library/get_link.py create mode 100644 awx/network_ui/library/get_process.py create mode 100644 awx/network_ui/library/get_stream.py create mode 100644 awx/network_ui/library/get_toolbox.py create mode 100644 awx/network_ui/library/get_toolboxitem.py create mode 100644 awx/network_ui/library/get_topology.py create mode 100644 awx/network_ui/library/get_topologyinventory.py create mode 100644 awx/network_ui/library/list_device.py create mode 100644 awx/network_ui/library/list_group.py create mode 100644 awx/network_ui/library/list_groupdevice.py create mode 100644 awx/network_ui/library/list_interface.py create mode 100644 awx/network_ui/library/list_link.py create mode 100644 awx/network_ui/library/list_process.py create mode 100644 awx/network_ui/library/list_stream.py create mode 100644 awx/network_ui/library/list_toolbox.py create mode 100644 awx/network_ui/library/list_toolboxitem.py create mode 100644 awx/network_ui/library/list_topology.py create mode 100644 awx/network_ui/library/list_topologyinventory.py create mode 100644 awx/network_ui/library/update_device.py create mode 100644 awx/network_ui/library/update_group.py create mode 100644 awx/network_ui/library/update_groupdevice.py create mode 100644 awx/network_ui/library/update_interface.py create mode 100644 awx/network_ui/library/update_link.py create mode 100644 awx/network_ui/library/update_process.py create mode 100644 awx/network_ui/library/update_stream.py create mode 100644 awx/network_ui/library/update_toolbox.py create mode 100644 awx/network_ui/library/update_toolboxitem.py create mode 100644 awx/network_ui/library/update_topology.py create mode 100644 awx/network_ui/library/update_topologyinventory.py create mode 100644 awx/network_ui/templates/action_plugins/create_model.pyt create mode 100644 awx/network_ui/templates/action_plugins/delete_model.pyt create mode 100644 awx/network_ui/templates/action_plugins/get_model.pyt create mode 100644 awx/network_ui/templates/action_plugins/list_model.pyt create mode 100644 awx/network_ui/templates/action_plugins/update_model.pyt create mode 100644 awx/network_ui/templates/library/create_model.pyt create mode 100644 awx/network_ui/templates/library/delete_model.pyt create mode 100644 awx/network_ui/templates/library/get_model.pyt create mode 100644 awx/network_ui/templates/library/list_model.pyt create mode 100644 awx/network_ui/templates/library/update_model.pyt create mode 100644 awx/network_ui/templates/tuples.pyt create mode 100644 awx/network_ui/templates/v1_api_client.pyt create mode 100644 awx/network_ui/templates/v1_api_serializers.pyt create mode 100644 awx/network_ui/templates/v1_api_urls.pyt create mode 100644 awx/network_ui/templates/v1_api_views.pyt create mode 100644 awx/network_ui/templates/v2_api_access.pyt create mode 100644 awx/network_ui/templates/v2_api_client.pyt create mode 100644 awx/network_ui/templates/v2_api_serializers.pyt create mode 100644 awx/network_ui/templates/v2_api_urls.pyt create mode 100644 awx/network_ui/templates/v2_api_views.pyt create mode 100644 awx/network_ui/tuples.py create mode 100644 awx/network_ui/v1_api_serializers.py create mode 100644 awx/network_ui/v1_api_urls.py create mode 100644 awx/network_ui/v1_api_views.py create mode 100644 awx/network_ui/v2_api_access.py create mode 100644 awx/network_ui/v2_api_serializers.py create mode 100644 awx/network_ui/v2_api_urls.py create mode 100644 awx/network_ui/v2_api_views.py diff --git a/awx/network_ui/Makefile b/awx/network_ui/Makefile index 80878d207d..b2466debc0 100644 --- a/awx/network_ui/Makefile +++ b/awx/network_ui/Makefile @@ -1,8 +1,12 @@ -.PHONY: all models admin +.PHONY: all models admin v1_api_serializers v1_api_views v1_api_urls v2_api_serializers v2_api_views v1_api_client v2_api_urls v2_api_access v2_api_client -all: models admin +all: tuples models admin v1_api_serializers v1_api_views v1_api_urls v2_api_serializers v2_api_views v1_api_client action_plugins v2_api_urls v2_api_access v2_api_client + +tuples: + jinja2 templates/tuples.pyt designs/models.yml > tuples.py + autopep8 -i tuples.py --ignore-local-config --max-line-length 160 models: jinja2 templates/models.pyt designs/models.yml > models.py @@ -11,3 +15,106 @@ models: admin: jinja2 templates/admin.pyt designs/models.yml > admin.py autopep8 -i admin.py --ignore-local-config --max-line-length 160 + +v1_api_serializers: + jinja2 templates/v1_api_serializers.pyt designs/models.yml > v1_api_serializers.py + autopep8 -i v1_api_serializers.py --ignore-local-config --max-line-length 160 + +v1_api_views: + jinja2 templates/v1_api_views.pyt designs/models.yml > v1_api_views.py + autopep8 -i v1_api_views.py --ignore-local-config --max-line-length 80 + +v1_api_urls: + jinja2 templates/v1_api_urls.pyt designs/models.yml > v1_api_urls.py + autopep8 -i v1_api_urls.py --ignore-local-config --max-line-length 160 + +v2_api_urls: + jinja2 templates/v2_api_urls.pyt designs/models.yml > v2_api_urls.py + autopep8 -i v2_api_urls.py --ignore-local-config --max-line-length 160 + +v2_api_access: + jinja2 templates/v2_api_access.pyt designs/models.yml > v2_api_access.py + autopep8 -i v2_api_access.py --ignore-local-config --max-line-length 160 + +v2_api_serializers: + jinja2 templates/v2_api_serializers.pyt designs/models.yml > v2_api_serializers.py + autopep8 -i v2_api_serializers.py --ignore-local-config --max-line-length 160 + +v2_api_views: + jinja2 templates/v2_api_views.pyt designs/models.yml > v2_api_views.py + autopep8 -i v2_api_views.py --ignore-local-config --max-line-length 160 + +v1_api_client: + jinja2 templates/v1_api_client.pyt designs/models.yml > client/v1_api_client.py + autopep8 -i client/v1_api_client.py --ignore-local-config --max-line-length 160 + +v2_api_client: + jinja2 templates/v2_api_client.pyt designs/models.yml > client/v2_api_client.py + autopep8 -i client/v2_api_client.py --ignore-local-config --max-line-length 160 + +action_plugins: ap_create_model ap_get_model ap_delete_model ap_update_model ap_list_model + +ap_create_model: + jinja2 templates/action_plugins/create_model.pyt designs/models.yml > action_plugins/create_model.py + cd action_plugins; csplit -k -f create_ create_model.py '/#----/' '{*}' + rm action_plugins/create_model.py + ./tools/fix_action_plugin_names.py action_plugins/create_* + autopep8 -i action_plugins/create_*.py --ignore-local-config --max-line-length 160 + jinja2 templates/library/create_model.pyt designs/models.yml > library/create_model.py + cd library; csplit -k -f create_ create_model.py '/#----/' '{*}' + rm library/create_model.py + ./tools/fix_action_plugin_names.py library/create_* + autopep8 -i library/create_*.py --ignore-local-config --max-line-length 160 + + +ap_update_model: + jinja2 templates/action_plugins/update_model.pyt designs/models.yml > action_plugins/update_model.py + cd action_plugins; csplit -k -f update_ update_model.py '/#----/' '{*}' + rm action_plugins/update_model.py + ./tools/fix_action_plugin_names.py action_plugins/update_* + autopep8 -i action_plugins/update_*.py --ignore-local-config --max-line-length 160 + jinja2 templates/library/update_model.pyt designs/models.yml > library/update_model.py + cd library; csplit -k -f update_ update_model.py '/#----/' '{*}' + rm library/update_model.py + ./tools/fix_action_plugin_names.py library/update_* + autopep8 -i library/update_*.py --ignore-local-config --max-line-length 160 + + +ap_get_model: + jinja2 templates/action_plugins/get_model.pyt designs/models.yml > action_plugins/get_model.py + cd action_plugins; csplit -k -f get_ get_model.py '/#----/' '{*}' + rm action_plugins/get_model.py + ./tools/fix_action_plugin_names.py action_plugins/get_* + autopep8 -i action_plugins/get_*.py --ignore-local-config --max-line-length 160 + jinja2 templates/library/get_model.pyt designs/models.yml > library/get_model.py + cd library; csplit -k -f get_ get_model.py '/#----/' '{*}' + rm library/get_model.py + ./tools/fix_action_plugin_names.py library/get_* + autopep8 -i library/get_*.py --ignore-local-config --max-line-length 160 + + +ap_delete_model: + jinja2 templates/action_plugins/delete_model.pyt designs/models.yml > action_plugins/delete_model.py + cd action_plugins; csplit -k -f delete_ delete_model.py '/#----/' '{*}' + rm action_plugins/delete_model.py + ./tools/fix_action_plugin_names.py action_plugins/delete_* + autopep8 -i action_plugins/delete_*.py --ignore-local-config --max-line-length 160 + jinja2 templates/library/delete_model.pyt designs/models.yml > library/delete_model.py + cd library; csplit -k -f delete_ delete_model.py '/#----/' '{*}' + rm library/delete_model.py + ./tools/fix_action_plugin_names.py library/delete_* + autopep8 -i library/delete_*.py --ignore-local-config --max-line-length 160 + + +ap_list_model: + jinja2 templates/action_plugins/list_model.pyt designs/models.yml > action_plugins/list_model.py + cd action_plugins; csplit -k -f list_ list_model.py '/#----/' '{*}' + rm action_plugins/list_model.py + ./tools/fix_action_plugin_names.py action_plugins/list_* + autopep8 -i action_plugins/list_*.py --ignore-local-config --max-line-length 160 + jinja2 templates/library/list_model.pyt designs/models.yml > library/list_model.py + cd library; csplit -k -f list_ list_model.py '/#----/' '{*}' + rm library/list_model.py + ./tools/fix_action_plugin_names.py library/list_* + autopep8 -i library/list_*.py --ignore-local-config --max-line-length 160 + diff --git a/awx/network_ui/action_plugins/create_device.py b/awx/network_ui/action_plugins/create_device.py new file mode 100644 index 0000000000..5e01680f15 --- /dev/null +++ b/awx/network_ui/action_plugins/create_device.py @@ -0,0 +1,61 @@ +#---- create_device + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + topology = self._task.args.get('topology', None) + name = self._task.args.get('name', None) + x = self._task.args.get('x', None) + y = self._task.args.get('y', None) + id = self._task.args.get('id', None) + type = self._task.args.get('type', None) + + interface_id_seq = self._task.args.get('interface_id_seq', 0) + process_id_seq = self._task.args.get('process_id_seq', 0) + host_id = self._task.args.get('host_id', 0) + + url = server + '/api/v2/canvas/device/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(topology=topology, + name=name, + x=x, + y=y, + id=id, + type=type, + interface_id_seq=interface_id_seq, + process_id_seq=process_id_seq, + host_id=host_id, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/create_group.py b/awx/network_ui/action_plugins/create_group.py new file mode 100644 index 0000000000..3106309b84 --- /dev/null +++ b/awx/network_ui/action_plugins/create_group.py @@ -0,0 +1,58 @@ +#---- create_group + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + id = self._task.args.get('id', None) + name = self._task.args.get('name', None) + x1 = self._task.args.get('x1', None) + y1 = self._task.args.get('y1', None) + x2 = self._task.args.get('x2', None) + y2 = self._task.args.get('y2', None) + topology = self._task.args.get('topology', None) + type = self._task.args.get('type', None) + + url = server + '/api/v2/canvas/group/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(id=id, + name=name, + x1=x1, + y1=y1, + x2=x2, + y2=y2, + topology=topology, + type=type, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/create_groupdevice.py b/awx/network_ui/action_plugins/create_groupdevice.py new file mode 100644 index 0000000000..dce3703c50 --- /dev/null +++ b/awx/network_ui/action_plugins/create_groupdevice.py @@ -0,0 +1,46 @@ +#---- create_groupdevice + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + group = self._task.args.get('group', None) + device = self._task.args.get('device', None) + + url = server + '/api/v2/canvas/groupdevice/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(group=group, + device=device, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/create_interface.py b/awx/network_ui/action_plugins/create_interface.py new file mode 100644 index 0000000000..cf63e9c082 --- /dev/null +++ b/awx/network_ui/action_plugins/create_interface.py @@ -0,0 +1,48 @@ +#---- create_interface + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + device = self._task.args.get('device', None) + name = self._task.args.get('name', None) + id = self._task.args.get('id', None) + + url = server + '/api/v2/canvas/interface/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(device=device, + name=name, + id=id, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/create_link.py b/awx/network_ui/action_plugins/create_link.py new file mode 100644 index 0000000000..7c17820d8c --- /dev/null +++ b/awx/network_ui/action_plugins/create_link.py @@ -0,0 +1,54 @@ +#---- create_link + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + from_device = self._task.args.get('from_device', None) + to_device = self._task.args.get('to_device', None) + from_interface = self._task.args.get('from_interface', None) + to_interface = self._task.args.get('to_interface', None) + id = self._task.args.get('id', None) + name = self._task.args.get('name', None) + + url = server + '/api/v2/canvas/link/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(from_device=from_device, + to_device=to_device, + from_interface=from_interface, + to_interface=to_interface, + id=id, + name=name, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/create_process.py b/awx/network_ui/action_plugins/create_process.py new file mode 100644 index 0000000000..ba2aacc5da --- /dev/null +++ b/awx/network_ui/action_plugins/create_process.py @@ -0,0 +1,51 @@ +#---- create_process + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + device = self._task.args.get('device', None) + name = self._task.args.get('name', None) + type = self._task.args.get('type', None) + + id = self._task.args.get('id', 0) + + url = server + '/api/v2/canvas/process/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(device=device, + name=name, + type=type, + id=id, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/create_stream.py b/awx/network_ui/action_plugins/create_stream.py new file mode 100644 index 0000000000..ccc14a32b2 --- /dev/null +++ b/awx/network_ui/action_plugins/create_stream.py @@ -0,0 +1,51 @@ +#---- create_stream + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + from_device = self._task.args.get('from_device', None) + to_device = self._task.args.get('to_device', None) + label = self._task.args.get('label', None) + + id = self._task.args.get('id', 0) + + url = server + '/api/v2/canvas/stream/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(from_device=from_device, + to_device=to_device, + label=label, + id=id, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/create_toolbox.py b/awx/network_ui/action_plugins/create_toolbox.py new file mode 100644 index 0000000000..5d7a0e0179 --- /dev/null +++ b/awx/network_ui/action_plugins/create_toolbox.py @@ -0,0 +1,44 @@ +#---- create_toolbox + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + name = self._task.args.get('name', None) + + url = server + '/api/v2/canvas/toolbox/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(name=name, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/create_toolboxitem.py b/awx/network_ui/action_plugins/create_toolboxitem.py new file mode 100644 index 0000000000..025a35b6b8 --- /dev/null +++ b/awx/network_ui/action_plugins/create_toolboxitem.py @@ -0,0 +1,46 @@ +#---- create_toolboxitem + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + toolbox = self._task.args.get('toolbox', None) + data = self._task.args.get('data', None) + + url = server + '/api/v2/canvas/toolboxitem/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(toolbox=toolbox, + data=data, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/create_topology.py b/awx/network_ui/action_plugins/create_topology.py new file mode 100644 index 0000000000..cd93e299dc --- /dev/null +++ b/awx/network_ui/action_plugins/create_topology.py @@ -0,0 +1,59 @@ +#---- create_topology + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + name = self._task.args.get('name', None) + scale = self._task.args.get('scale', None) + panX = self._task.args.get('panX', None) + panY = self._task.args.get('panY', None) + + device_id_seq = self._task.args.get('device_id_seq', 0) + link_id_seq = self._task.args.get('link_id_seq', 0) + group_id_seq = self._task.args.get('group_id_seq', 0) + stream_id_seq = self._task.args.get('stream_id_seq', 0) + + url = server + '/api/v2/canvas/topology/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(name=name, + scale=scale, + panX=panX, + panY=panY, + device_id_seq=device_id_seq, + link_id_seq=link_id_seq, + group_id_seq=group_id_seq, + stream_id_seq=stream_id_seq, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/create_topologyinventory.py b/awx/network_ui/action_plugins/create_topologyinventory.py new file mode 100644 index 0000000000..bd6e5648fd --- /dev/null +++ b/awx/network_ui/action_plugins/create_topologyinventory.py @@ -0,0 +1,46 @@ +#---- create_topologyinventory + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) + + topology = self._task.args.get('topology', None) + inventory_id = self._task.args.get('inventory_id', None) + + url = server + '/api/v2/canvas/topologyinventory/' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict(topology=topology, + inventory_id=inventory_id, + )), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result diff --git a/awx/network_ui/action_plugins/delete_device.py b/awx/network_ui/action_plugins/delete_device.py new file mode 100644 index 0000000000..76f5fdac55 --- /dev/null +++ b/awx/network_ui/action_plugins/delete_device.py @@ -0,0 +1,29 @@ +#---- delete_device + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + device_id = self._task.args.get('device_id', None) + + url = server + '/api/v2/canvas/device/' + str(device_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/delete_group.py b/awx/network_ui/action_plugins/delete_group.py new file mode 100644 index 0000000000..4c95d49a14 --- /dev/null +++ b/awx/network_ui/action_plugins/delete_group.py @@ -0,0 +1,29 @@ +#---- delete_group + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + group_id = self._task.args.get('group_id', None) + + url = server + '/api/v2/canvas/group/' + str(group_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/delete_groupdevice.py b/awx/network_ui/action_plugins/delete_groupdevice.py new file mode 100644 index 0000000000..dac265cc31 --- /dev/null +++ b/awx/network_ui/action_plugins/delete_groupdevice.py @@ -0,0 +1,29 @@ +#---- delete_groupdevice + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + group_device_id = self._task.args.get('group_device_id', None) + + url = server + '/api/v2/canvas/groupdevice/' + str(group_device_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/delete_interface.py b/awx/network_ui/action_plugins/delete_interface.py new file mode 100644 index 0000000000..9797fc0f17 --- /dev/null +++ b/awx/network_ui/action_plugins/delete_interface.py @@ -0,0 +1,29 @@ +#---- delete_interface + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + interface_id = self._task.args.get('interface_id', None) + + url = server + '/api/v2/canvas/interface/' + str(interface_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/delete_link.py b/awx/network_ui/action_plugins/delete_link.py new file mode 100644 index 0000000000..f78e472a2b --- /dev/null +++ b/awx/network_ui/action_plugins/delete_link.py @@ -0,0 +1,29 @@ +#---- delete_link + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + link_id = self._task.args.get('link_id', None) + + url = server + '/api/v2/canvas/link/' + str(link_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/delete_process.py b/awx/network_ui/action_plugins/delete_process.py new file mode 100644 index 0000000000..2febcbb9f2 --- /dev/null +++ b/awx/network_ui/action_plugins/delete_process.py @@ -0,0 +1,29 @@ +#---- delete_process + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + process_id = self._task.args.get('process_id', None) + + url = server + '/api/v2/canvas/process/' + str(process_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/delete_stream.py b/awx/network_ui/action_plugins/delete_stream.py new file mode 100644 index 0000000000..f604ad7bdb --- /dev/null +++ b/awx/network_ui/action_plugins/delete_stream.py @@ -0,0 +1,29 @@ +#---- delete_stream + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + stream_id = self._task.args.get('stream_id', None) + + url = server + '/api/v2/canvas/stream/' + str(stream_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/delete_toolbox.py b/awx/network_ui/action_plugins/delete_toolbox.py new file mode 100644 index 0000000000..544f937771 --- /dev/null +++ b/awx/network_ui/action_plugins/delete_toolbox.py @@ -0,0 +1,29 @@ +#---- delete_toolbox + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + toolbox_id = self._task.args.get('toolbox_id', None) + + url = server + '/api/v2/canvas/toolbox/' + str(toolbox_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/delete_toolboxitem.py b/awx/network_ui/action_plugins/delete_toolboxitem.py new file mode 100644 index 0000000000..79a20ed9a3 --- /dev/null +++ b/awx/network_ui/action_plugins/delete_toolboxitem.py @@ -0,0 +1,29 @@ +#---- delete_toolboxitem + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + toolbox_item_id = self._task.args.get('toolbox_item_id', None) + + url = server + '/api/v2/canvas/toolboxitem/' + str(toolbox_item_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/delete_topology.py b/awx/network_ui/action_plugins/delete_topology.py new file mode 100644 index 0000000000..bacbda8da8 --- /dev/null +++ b/awx/network_ui/action_plugins/delete_topology.py @@ -0,0 +1,29 @@ +#---- delete_topology + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + topology_id = self._task.args.get('topology_id', None) + + url = server + '/api/v2/canvas/topology/' + str(topology_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/delete_topologyinventory.py b/awx/network_ui/action_plugins/delete_topologyinventory.py new file mode 100644 index 0000000000..dd3cedb646 --- /dev/null +++ b/awx/network_ui/action_plugins/delete_topologyinventory.py @@ -0,0 +1,29 @@ +#---- delete_topologyinventory + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + topology_inventory_id = self._task.args.get('topology_inventory_id', None) + + url = server + '/api/v2/canvas/topologyinventory/' + str(topology_inventory_id) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result diff --git a/awx/network_ui/action_plugins/get_device.py b/awx/network_ui/action_plugins/get_device.py new file mode 100644 index 0000000000..9953a26cb8 --- /dev/null +++ b/awx/network_ui/action_plugins/get_device.py @@ -0,0 +1,32 @@ +#---- get_device + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + device_id = self._task.args.get('device_id', None) + + url = server + '/api/v2/canvas/device/' + str(device_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/get_group.py b/awx/network_ui/action_plugins/get_group.py new file mode 100644 index 0000000000..4894ed63ce --- /dev/null +++ b/awx/network_ui/action_plugins/get_group.py @@ -0,0 +1,32 @@ +#---- get_group + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + group_id = self._task.args.get('group_id', None) + + url = server + '/api/v2/canvas/group/' + str(group_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/get_groupdevice.py b/awx/network_ui/action_plugins/get_groupdevice.py new file mode 100644 index 0000000000..2207ac0d34 --- /dev/null +++ b/awx/network_ui/action_plugins/get_groupdevice.py @@ -0,0 +1,32 @@ +#---- get_groupdevice + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + group_device_id = self._task.args.get('group_device_id', None) + + url = server + '/api/v2/canvas/groupdevice/' + str(group_device_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/get_interface.py b/awx/network_ui/action_plugins/get_interface.py new file mode 100644 index 0000000000..97c7e3cad7 --- /dev/null +++ b/awx/network_ui/action_plugins/get_interface.py @@ -0,0 +1,32 @@ +#---- get_interface + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + interface_id = self._task.args.get('interface_id', None) + + url = server + '/api/v2/canvas/interface/' + str(interface_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/get_link.py b/awx/network_ui/action_plugins/get_link.py new file mode 100644 index 0000000000..12c626fde1 --- /dev/null +++ b/awx/network_ui/action_plugins/get_link.py @@ -0,0 +1,32 @@ +#---- get_link + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + link_id = self._task.args.get('link_id', None) + + url = server + '/api/v2/canvas/link/' + str(link_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/get_process.py b/awx/network_ui/action_plugins/get_process.py new file mode 100644 index 0000000000..a83dd17672 --- /dev/null +++ b/awx/network_ui/action_plugins/get_process.py @@ -0,0 +1,32 @@ +#---- get_process + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + process_id = self._task.args.get('process_id', None) + + url = server + '/api/v2/canvas/process/' + str(process_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/get_stream.py b/awx/network_ui/action_plugins/get_stream.py new file mode 100644 index 0000000000..d4ad6c4f97 --- /dev/null +++ b/awx/network_ui/action_plugins/get_stream.py @@ -0,0 +1,32 @@ +#---- get_stream + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + stream_id = self._task.args.get('stream_id', None) + + url = server + '/api/v2/canvas/stream/' + str(stream_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/get_toolbox.py b/awx/network_ui/action_plugins/get_toolbox.py new file mode 100644 index 0000000000..83fa6d87d1 --- /dev/null +++ b/awx/network_ui/action_plugins/get_toolbox.py @@ -0,0 +1,32 @@ +#---- get_toolbox + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + toolbox_id = self._task.args.get('toolbox_id', None) + + url = server + '/api/v2/canvas/toolbox/' + str(toolbox_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/get_toolboxitem.py b/awx/network_ui/action_plugins/get_toolboxitem.py new file mode 100644 index 0000000000..f80990dbba --- /dev/null +++ b/awx/network_ui/action_plugins/get_toolboxitem.py @@ -0,0 +1,32 @@ +#---- get_toolboxitem + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + toolbox_item_id = self._task.args.get('toolbox_item_id', None) + + url = server + '/api/v2/canvas/toolboxitem/' + str(toolbox_item_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/get_topology.py b/awx/network_ui/action_plugins/get_topology.py new file mode 100644 index 0000000000..4a5b0229a6 --- /dev/null +++ b/awx/network_ui/action_plugins/get_topology.py @@ -0,0 +1,32 @@ +#---- get_topology + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + topology_id = self._task.args.get('topology_id', None) + + url = server + '/api/v2/canvas/topology/' + str(topology_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/get_topologyinventory.py b/awx/network_ui/action_plugins/get_topologyinventory.py new file mode 100644 index 0000000000..39a4bbf0a5 --- /dev/null +++ b/awx/network_ui/action_plugins/get_topologyinventory.py @@ -0,0 +1,32 @@ +#---- get_topologyinventory + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + topology_inventory_id = self._task.args.get('topology_inventory_id', None) + + url = server + '/api/v2/canvas/topologyinventory/' + str(topology_inventory_id) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/list_device.py b/awx/network_ui/action_plugins/list_device.py new file mode 100644 index 0000000000..1c371e88c3 --- /dev/null +++ b/awx/network_ui/action_plugins/list_device.py @@ -0,0 +1,57 @@ +#---- list_device + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + device_id = self._task.args.get('device_id', None) + topology = self._task.args.get('topology', None) + name = self._task.args.get('name', None) + x = self._task.args.get('x', None) + y = self._task.args.get('y', None) + id = self._task.args.get('id', None) + type = self._task.args.get('type', None) + interface_id_seq = self._task.args.get('interface_id_seq', None) + process_id_seq = self._task.args.get('process_id_seq', None) + host_id = self._task.args.get('host_id', None) + + filter_data = dict(device_id=device_id, + topology=topology, + name=name, + x=x, + y=y, + id=id, + type=type, + interface_id_seq=interface_id_seq, + process_id_seq=process_id_seq, + host_id=host_id, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/device/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/list_group.py b/awx/network_ui/action_plugins/list_group.py new file mode 100644 index 0000000000..b90c837387 --- /dev/null +++ b/awx/network_ui/action_plugins/list_group.py @@ -0,0 +1,55 @@ +#---- list_group + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + group_id = self._task.args.get('group_id', None) + id = self._task.args.get('id', None) + name = self._task.args.get('name', None) + x1 = self._task.args.get('x1', None) + y1 = self._task.args.get('y1', None) + x2 = self._task.args.get('x2', None) + y2 = self._task.args.get('y2', None) + topology = self._task.args.get('topology', None) + type = self._task.args.get('type', None) + + filter_data = dict(group_id=group_id, + id=id, + name=name, + x1=x1, + y1=y1, + x2=x2, + y2=y2, + topology=topology, + type=type, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/group/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/list_groupdevice.py b/awx/network_ui/action_plugins/list_groupdevice.py new file mode 100644 index 0000000000..08fea8b75f --- /dev/null +++ b/awx/network_ui/action_plugins/list_groupdevice.py @@ -0,0 +1,43 @@ +#---- list_groupdevice + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + group_device_id = self._task.args.get('group_device_id', None) + group = self._task.args.get('group', None) + device = self._task.args.get('device', None) + + filter_data = dict(group_device_id=group_device_id, + group=group, + device=device, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/groupdevice/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/list_interface.py b/awx/network_ui/action_plugins/list_interface.py new file mode 100644 index 0000000000..abb8f7d99b --- /dev/null +++ b/awx/network_ui/action_plugins/list_interface.py @@ -0,0 +1,45 @@ +#---- list_interface + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + interface_id = self._task.args.get('interface_id', None) + device = self._task.args.get('device', None) + name = self._task.args.get('name', None) + id = self._task.args.get('id', None) + + filter_data = dict(interface_id=interface_id, + device=device, + name=name, + id=id, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/interface/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/list_link.py b/awx/network_ui/action_plugins/list_link.py new file mode 100644 index 0000000000..b3439764a9 --- /dev/null +++ b/awx/network_ui/action_plugins/list_link.py @@ -0,0 +1,51 @@ +#---- list_link + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + link_id = self._task.args.get('link_id', None) + from_device = self._task.args.get('from_device', None) + to_device = self._task.args.get('to_device', None) + from_interface = self._task.args.get('from_interface', None) + to_interface = self._task.args.get('to_interface', None) + id = self._task.args.get('id', None) + name = self._task.args.get('name', None) + + filter_data = dict(link_id=link_id, + from_device=from_device, + to_device=to_device, + from_interface=from_interface, + to_interface=to_interface, + id=id, + name=name, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/link/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/list_process.py b/awx/network_ui/action_plugins/list_process.py new file mode 100644 index 0000000000..27c09870ee --- /dev/null +++ b/awx/network_ui/action_plugins/list_process.py @@ -0,0 +1,47 @@ +#---- list_process + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + process_id = self._task.args.get('process_id', None) + device = self._task.args.get('device', None) + name = self._task.args.get('name', None) + type = self._task.args.get('type', None) + id = self._task.args.get('id', None) + + filter_data = dict(process_id=process_id, + device=device, + name=name, + type=type, + id=id, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/process/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/list_stream.py b/awx/network_ui/action_plugins/list_stream.py new file mode 100644 index 0000000000..980aac125b --- /dev/null +++ b/awx/network_ui/action_plugins/list_stream.py @@ -0,0 +1,47 @@ +#---- list_stream + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + stream_id = self._task.args.get('stream_id', None) + from_device = self._task.args.get('from_device', None) + to_device = self._task.args.get('to_device', None) + label = self._task.args.get('label', None) + id = self._task.args.get('id', None) + + filter_data = dict(stream_id=stream_id, + from_device=from_device, + to_device=to_device, + label=label, + id=id, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/stream/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/list_toolbox.py b/awx/network_ui/action_plugins/list_toolbox.py new file mode 100644 index 0000000000..3f4b3e6854 --- /dev/null +++ b/awx/network_ui/action_plugins/list_toolbox.py @@ -0,0 +1,41 @@ +#---- list_toolbox + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + toolbox_id = self._task.args.get('toolbox_id', None) + name = self._task.args.get('name', None) + + filter_data = dict(toolbox_id=toolbox_id, + name=name, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/toolbox/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/list_toolboxitem.py b/awx/network_ui/action_plugins/list_toolboxitem.py new file mode 100644 index 0000000000..5fc70a6e17 --- /dev/null +++ b/awx/network_ui/action_plugins/list_toolboxitem.py @@ -0,0 +1,43 @@ +#---- list_toolboxitem + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + toolbox_item_id = self._task.args.get('toolbox_item_id', None) + toolbox = self._task.args.get('toolbox', None) + data = self._task.args.get('data', None) + + filter_data = dict(toolbox_item_id=toolbox_item_id, + toolbox=toolbox, + data=data, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/toolboxitem/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/list_topology.py b/awx/network_ui/action_plugins/list_topology.py new file mode 100644 index 0000000000..50a7448849 --- /dev/null +++ b/awx/network_ui/action_plugins/list_topology.py @@ -0,0 +1,55 @@ +#---- list_topology + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + topology_id = self._task.args.get('topology_id', None) + name = self._task.args.get('name', None) + scale = self._task.args.get('scale', None) + panX = self._task.args.get('panX', None) + panY = self._task.args.get('panY', None) + device_id_seq = self._task.args.get('device_id_seq', None) + link_id_seq = self._task.args.get('link_id_seq', None) + group_id_seq = self._task.args.get('group_id_seq', None) + stream_id_seq = self._task.args.get('stream_id_seq', None) + + filter_data = dict(topology_id=topology_id, + name=name, + scale=scale, + panX=panX, + panY=panY, + device_id_seq=device_id_seq, + link_id_seq=link_id_seq, + group_id_seq=group_id_seq, + stream_id_seq=stream_id_seq, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/topology/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/list_topologyinventory.py b/awx/network_ui/action_plugins/list_topologyinventory.py new file mode 100644 index 0000000000..566f0a8442 --- /dev/null +++ b/awx/network_ui/action_plugins/list_topologyinventory.py @@ -0,0 +1,43 @@ +#---- list_topologyinventory + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + topology_inventory_id = self._task.args.get('topology_inventory_id', None) + topology = self._task.args.get('topology', None) + inventory_id = self._task.args.get('inventory_id', None) + + filter_data = dict(topology_inventory_id=topology_inventory_id, + topology=topology, + inventory_id=inventory_id, + ) + filter_data = {x: y for x, y in filter_data.iteritems() if y is not None} + + url = '/api/v2/canvas/topologyinventory/' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result diff --git a/awx/network_ui/action_plugins/update_device.py b/awx/network_ui/action_plugins/update_device.py new file mode 100644 index 0000000000..13c15eaf4e --- /dev/null +++ b/awx/network_ui/action_plugins/update_device.py @@ -0,0 +1,56 @@ +#---- update_device + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + device_id = self._task.args.get('device_id', None) + topology = self._task.args.get('topology', None) + name = self._task.args.get('name', None) + x = self._task.args.get('x', None) + y = self._task.args.get('y', None) + id = self._task.args.get('id', None) + type = self._task.args.get('type', None) + interface_id_seq = self._task.args.get('interface_id_seq', None) + process_id_seq = self._task.args.get('process_id_seq', None) + host_id = self._task.args.get('host_id', None) + + url = server + '/api/v2/canvas/device/' + str(device_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(topology=topology, + name=name, + x=x, + y=y, + id=id, + type=type, + interface_id_seq=interface_id_seq, + process_id_seq=process_id_seq, + host_id=host_id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/update_group.py b/awx/network_ui/action_plugins/update_group.py new file mode 100644 index 0000000000..f985682366 --- /dev/null +++ b/awx/network_ui/action_plugins/update_group.py @@ -0,0 +1,54 @@ +#---- update_group + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + group_id = self._task.args.get('group_id', None) + id = self._task.args.get('id', None) + name = self._task.args.get('name', None) + x1 = self._task.args.get('x1', None) + y1 = self._task.args.get('y1', None) + x2 = self._task.args.get('x2', None) + y2 = self._task.args.get('y2', None) + topology = self._task.args.get('topology', None) + type = self._task.args.get('type', None) + + url = server + '/api/v2/canvas/group/' + str(group_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(id=id, + name=name, + x1=x1, + y1=y1, + x2=x2, + y2=y2, + topology=topology, + type=type, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/update_groupdevice.py b/awx/network_ui/action_plugins/update_groupdevice.py new file mode 100644 index 0000000000..5c6a493154 --- /dev/null +++ b/awx/network_ui/action_plugins/update_groupdevice.py @@ -0,0 +1,42 @@ +#---- update_groupdevice + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + group_device_id = self._task.args.get('group_device_id', None) + group = self._task.args.get('group', None) + device = self._task.args.get('device', None) + + url = server + '/api/v2/canvas/groupdevice/' + str(group_device_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(group=group, + device=device, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/update_interface.py b/awx/network_ui/action_plugins/update_interface.py new file mode 100644 index 0000000000..d9a1e0d7ab --- /dev/null +++ b/awx/network_ui/action_plugins/update_interface.py @@ -0,0 +1,44 @@ +#---- update_interface + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + interface_id = self._task.args.get('interface_id', None) + device = self._task.args.get('device', None) + name = self._task.args.get('name', None) + id = self._task.args.get('id', None) + + url = server + '/api/v2/canvas/interface/' + str(interface_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(device=device, + name=name, + id=id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/update_link.py b/awx/network_ui/action_plugins/update_link.py new file mode 100644 index 0000000000..26345cea75 --- /dev/null +++ b/awx/network_ui/action_plugins/update_link.py @@ -0,0 +1,50 @@ +#---- update_link + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + link_id = self._task.args.get('link_id', None) + from_device = self._task.args.get('from_device', None) + to_device = self._task.args.get('to_device', None) + from_interface = self._task.args.get('from_interface', None) + to_interface = self._task.args.get('to_interface', None) + id = self._task.args.get('id', None) + name = self._task.args.get('name', None) + + url = server + '/api/v2/canvas/link/' + str(link_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(from_device=from_device, + to_device=to_device, + from_interface=from_interface, + to_interface=to_interface, + id=id, + name=name, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/update_process.py b/awx/network_ui/action_plugins/update_process.py new file mode 100644 index 0000000000..577baa29a4 --- /dev/null +++ b/awx/network_ui/action_plugins/update_process.py @@ -0,0 +1,46 @@ +#---- update_process + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + process_id = self._task.args.get('process_id', None) + device = self._task.args.get('device', None) + name = self._task.args.get('name', None) + type = self._task.args.get('type', None) + id = self._task.args.get('id', None) + + url = server + '/api/v2/canvas/process/' + str(process_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(device=device, + name=name, + type=type, + id=id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/update_stream.py b/awx/network_ui/action_plugins/update_stream.py new file mode 100644 index 0000000000..d91e2b365e --- /dev/null +++ b/awx/network_ui/action_plugins/update_stream.py @@ -0,0 +1,46 @@ +#---- update_stream + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + stream_id = self._task.args.get('stream_id', None) + from_device = self._task.args.get('from_device', None) + to_device = self._task.args.get('to_device', None) + label = self._task.args.get('label', None) + id = self._task.args.get('id', None) + + url = server + '/api/v2/canvas/stream/' + str(stream_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(from_device=from_device, + to_device=to_device, + label=label, + id=id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/update_toolbox.py b/awx/network_ui/action_plugins/update_toolbox.py new file mode 100644 index 0000000000..0f16adefa3 --- /dev/null +++ b/awx/network_ui/action_plugins/update_toolbox.py @@ -0,0 +1,40 @@ +#---- update_toolbox + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + toolbox_id = self._task.args.get('toolbox_id', None) + name = self._task.args.get('name', None) + + url = server + '/api/v2/canvas/toolbox/' + str(toolbox_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(name=name, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/update_toolboxitem.py b/awx/network_ui/action_plugins/update_toolboxitem.py new file mode 100644 index 0000000000..5b163986c4 --- /dev/null +++ b/awx/network_ui/action_plugins/update_toolboxitem.py @@ -0,0 +1,42 @@ +#---- update_toolboxitem + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + toolbox_item_id = self._task.args.get('toolbox_item_id', None) + toolbox = self._task.args.get('toolbox', None) + data = self._task.args.get('data', None) + + url = server + '/api/v2/canvas/toolboxitem/' + str(toolbox_item_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(toolbox=toolbox, + data=data, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/update_topology.py b/awx/network_ui/action_plugins/update_topology.py new file mode 100644 index 0000000000..696135f6f6 --- /dev/null +++ b/awx/network_ui/action_plugins/update_topology.py @@ -0,0 +1,54 @@ +#---- update_topology + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + topology_id = self._task.args.get('topology_id', None) + name = self._task.args.get('name', None) + scale = self._task.args.get('scale', None) + panX = self._task.args.get('panX', None) + panY = self._task.args.get('panY', None) + device_id_seq = self._task.args.get('device_id_seq', None) + link_id_seq = self._task.args.get('link_id_seq', None) + group_id_seq = self._task.args.get('group_id_seq', None) + stream_id_seq = self._task.args.get('stream_id_seq', None) + + url = server + '/api/v2/canvas/topology/' + str(topology_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(name=name, + scale=scale, + panX=panX, + panY=panY, + device_id_seq=device_id_seq, + link_id_seq=link_id_seq, + group_id_seq=group_id_seq, + stream_id_seq=stream_id_seq, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/action_plugins/update_topologyinventory.py b/awx/network_ui/action_plugins/update_topologyinventory.py new file mode 100644 index 0000000000..38b8281a2a --- /dev/null +++ b/awx/network_ui/action_plugins/update_topologyinventory.py @@ -0,0 +1,42 @@ +#---- update_topologyinventory + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + + topology_inventory_id = self._task.args.get('topology_inventory_id', None) + topology = self._task.args.get('topology', None) + inventory_id = self._task.args.get('inventory_id', None) + + url = server + '/api/v2/canvas/topologyinventory/' + str(topology_inventory_id) + '/' + headers = {'content-type': 'application/json'} + data = dict(topology=topology, + inventory_id=inventory_id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result diff --git a/awx/network_ui/admin.py b/awx/network_ui/admin.py index a1bb367306..2e640e542d 100644 --- a/awx/network_ui/admin.py +++ b/awx/network_ui/admin.py @@ -69,7 +69,7 @@ admin.site.register(Link, LinkAdmin) class TopologyAdmin(admin.ModelAdmin): fields = ('name', 'scale', 'panX', 'panY', 'device_id_seq', 'link_id_seq', 'group_id_seq', 'stream_id_seq',) - raw_id_fields = ('group_id_seq',) + raw_id_fields = () admin.site.register(Topology, TopologyAdmin) diff --git a/awx/network_ui/client/README.md b/awx/network_ui/client/README.md new file mode 100644 index 0000000000..74324e7f67 --- /dev/null +++ b/awx/network_ui/client/README.md @@ -0,0 +1,3 @@ +API client for the networking visualization. + + diff --git a/awx/network_ui/client/conf.py b/awx/network_ui/client/conf.py new file mode 100644 index 0000000000..bc8eeb7344 --- /dev/null +++ b/awx/network_ui/client/conf.py @@ -0,0 +1,11 @@ + +class _Settings(object): + + def __init__(self): + self.SERVER = 'https://meganuke:8043' + self.SSL_VERIFY = False + self.user = None + self.password = None + + +settings = _Settings() diff --git a/awx/network_ui/client/networking_visualization_client.py b/awx/network_ui/client/networking_visualization_client.py new file mode 100755 index 0000000000..a5a2d81e19 --- /dev/null +++ b/awx/network_ui/client/networking_visualization_client.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Usage: + networking_visualization_client.py [options] (create|list|get|update|delete) [device|topology|interface|link] [...] + +Options: + -h, --help Show this page + --user= User + --password-file=|-p= Password file + --debug Show debug logging + --verbose Show verbose logging +""" +from docopt import docopt +import logging +import sys +from getpass import getpass + +from conf import settings +import json +import os + +import v2_api_client + + +logger = logging.getLogger('networking_visualization_client') + + +def main(args=None): + try: + if args is None: + args = sys.argv[1:] + parsed_args = docopt(__doc__, args) + if parsed_args['--debug']: + logging.basicConfig(level=logging.DEBUG) + elif parsed_args['--verbose']: + logging.basicConfig(level=logging.INFO) + else: + logging.basicConfig(level=logging.WARNING) + + settings.user = parsed_args['--user'] + if parsed_args['--password-file'] and os.path.exists(os.path.abspath(parsed_args['--password-file'])): + with open(os.path.abspath(parsed_args['--password-file'])) as f: + settings.password = f.read().strip() + else: + settings.password = getpass() + query_filter = {} + if parsed_args['']: + for key_value in parsed_args['']: + if "=" in key_value: + key, _, value = key_value.partition("=") + if value.lower() in ["true", "yes"]: + query_filter[key] = True + elif value.lower() in ["false", "no"]: + query_filter[key] = False + else: + try: + query_filter[key] = int(value) + except ValueError: + try: + query_filter[key] = float(value) + except ValueError: + query_filter[key] = value + else: + raise Exception("Filters should be in the form of 'key=value'") + + operation = ('get' if parsed_args['get'] else + 'list' if parsed_args['list'] else + 'create' if parsed_args['create'] else + 'delete' if parsed_args['delete'] else + 'update' if parsed_args['update'] else None) + + if (parsed_args['topology']): + result = v2_api_client.__dict__[operation + "_topology"](**query_filter) + elif (parsed_args['device']): + result = v2_api_client.__dict__[operation + "_device"](**query_filter) + elif (parsed_args['interface']): + result = v2_api_client.__dict__[operation + "_interface"](**query_filter) + elif (parsed_args['link']): + result = v2_api_client.__dict__[operation + "_link"](**query_filter) + if isinstance(result, dict) or isinstance(result, list): + print json.dumps(result, sort_keys=True, indent=4) + + except BaseException, e: + print ("Error: {0}".format(e)) + raise + return 1 + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) + diff --git a/awx/network_ui/client/requirements.txt b/awx/network_ui/client/requirements.txt new file mode 100644 index 0000000000..f7d3503ddb --- /dev/null +++ b/awx/network_ui/client/requirements.txt @@ -0,0 +1,3 @@ +docopt +requests +pyyaml diff --git a/awx/network_ui/client/util.py b/awx/network_ui/client/util.py new file mode 100644 index 0000000000..3a54e9221d --- /dev/null +++ b/awx/network_ui/client/util.py @@ -0,0 +1,27 @@ + + +import requests + +from conf import settings + + +def get_url(): + return settings.SERVER + + +def get_auth(): + return (settings.user, settings.password) + + +def get_verify(): + return settings.SSL_VERIFY + + +def unpaginate(server, url, verify, auth, filter_data): + results = [] + while url is not None: + url = "{0}{1}".format(server, url) + data = requests.get(url, verify=verify, auth=auth, params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + return results diff --git a/awx/network_ui/client/v1_api_client.py b/awx/network_ui/client/v1_api_client.py new file mode 100644 index 0000000000..35b386543c --- /dev/null +++ b/awx/network_ui/client/v1_api_client.py @@ -0,0 +1,586 @@ + +import requests + +import util +import json +from collections import namedtuple + + +Device = namedtuple('Device', ['device_id', + 'topology', + 'name', + 'x', + 'y', + 'id', + 'type', + 'interface_id_seq', + 'process_id_seq', + 'host_id', + ]) + +Link = namedtuple('Link', ['link_id', + 'from_device', + 'to_device', + 'from_interface', + 'to_interface', + 'id', + 'name', + ]) + +Topology = namedtuple('Topology', ['topology_id', + 'name', + 'scale', + 'panX', + 'panY', + 'device_id_seq', + 'link_id_seq', + 'group_id_seq', + 'stream_id_seq', + ]) + +Interface = namedtuple('Interface', ['interface_id', + 'device', + 'name', + 'id', + ]) + +Group = namedtuple('Group', ['group_id', + 'id', + 'name', + 'x1', + 'y1', + 'x2', + 'y2', + 'topology', + 'type', + 'inventory_group_id', + ]) + +GroupDevice = namedtuple('GroupDevice', ['group_device_id', + 'group', + 'device', + ]) + +Stream = namedtuple('Stream', ['stream_id', + 'from_device', + 'to_device', + 'label', + 'id', + ]) + +Process = namedtuple('Process', ['process_id', + 'device', + 'name', + 'type', + 'id', + ]) + +Toolbox = namedtuple('Toolbox', ['toolbox_id', + 'name', + ]) + +ToolboxItem = namedtuple('ToolboxItem', ['toolbox_item_id', + 'toolbox', + 'data', + ]) + +TopologyInventory = namedtuple('TopologyInventory', ['topology_inventory_id', + 'topology', + 'inventory_id', + ]) + + +def list_device(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/device/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_device(device_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/device/" + str(device_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_device(topology, name, x, y, id, type, interface_id_seq=0, process_id_seq=0, host_id=0,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/device/", data=json.dumps(dict(topology=topology, + name=name, + x=x, + y=y, + id=id, + type=type, + interface_id_seq=interface_id_seq, + process_id_seq=process_id_seq, + host_id=host_id, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_device(device_id, topology=None, name=None, x=None, y=None, id=None, type=None, interface_id_seq=None, process_id_seq=None, host_id=None,): + headers = {'content-type': 'application/json'} + data = dict(topology=topology, + name=name, + x=x, + y=y, + id=id, + type=type, + interface_id_seq=interface_id_seq, + process_id_seq=process_id_seq, + host_id=host_id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/device/" + str(device_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_device(device_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/device/" + str(device_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_link(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/link/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_link(link_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/link/" + str(link_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_link(from_device, to_device, from_interface, to_interface, id, name,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/link/", data=json.dumps(dict(from_device=from_device, + to_device=to_device, + from_interface=from_interface, + to_interface=to_interface, + id=id, + name=name, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_link(link_id, from_device=None, to_device=None, from_interface=None, to_interface=None, id=None, name=None,): + headers = {'content-type': 'application/json'} + data = dict(from_device=from_device, + to_device=to_device, + from_interface=from_interface, + to_interface=to_interface, + id=id, + name=name, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/link/" + str(link_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_link(link_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/link/" + str(link_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_topology(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/topology/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_topology(topology_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/topology/" + str(topology_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_topology(name, scale, panX, panY, device_id_seq=0, link_id_seq=0, group_id_seq=0, stream_id_seq=0,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/topology/", data=json.dumps(dict(name=name, + scale=scale, + panX=panX, + panY=panY, + device_id_seq=device_id_seq, + link_id_seq=link_id_seq, + group_id_seq=group_id_seq, + stream_id_seq=stream_id_seq, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_topology(topology_id, name=None, scale=None, panX=None, panY=None, device_id_seq=None, link_id_seq=None, group_id_seq=None, stream_id_seq=None,): + headers = {'content-type': 'application/json'} + data = dict(name=name, + scale=scale, + panX=panX, + panY=panY, + device_id_seq=device_id_seq, + link_id_seq=link_id_seq, + group_id_seq=group_id_seq, + stream_id_seq=stream_id_seq, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/topology/" + str(topology_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_topology(topology_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/topology/" + str(topology_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_interface(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/interface/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_interface(interface_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/interface/" + str(interface_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_interface(device, name, id,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/interface/", data=json.dumps(dict(device=device, + name=name, + id=id, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_interface(interface_id, device=None, name=None, id=None,): + headers = {'content-type': 'application/json'} + data = dict(device=device, + name=name, + id=id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/interface/" + str(interface_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_interface(interface_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/interface/" + str(interface_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_group(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/group/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_group(group_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/group/" + str(group_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_group(id, name, x1, y1, x2, y2, topology, type,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/group/", data=json.dumps(dict(id=id, + name=name, + x1=x1, + y1=y1, + x2=x2, + y2=y2, + topology=topology, + type=type, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_group(group_id, id=None, name=None, x1=None, y1=None, x2=None, y2=None, topology=None, type=None,): + headers = {'content-type': 'application/json'} + data = dict(id=id, + name=name, + x1=x1, + y1=y1, + x2=x2, + y2=y2, + topology=topology, + type=type, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/group/" + str(group_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_group(group_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/group/" + str(group_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_groupdevice(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/groupdevice/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_groupdevice(group_device_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/groupdevice/" + str(group_device_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_groupdevice(group, device,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/groupdevice/", data=json.dumps(dict(group=group, + device=device, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_groupdevice(group_device_id, group=None, device=None,): + headers = {'content-type': 'application/json'} + data = dict(group=group, + device=device, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/groupdevice/" + str(group_device_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_groupdevice(group_device_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/groupdevice/" + str(group_device_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_stream(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/stream/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_stream(stream_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/stream/" + str(stream_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_stream(from_device, to_device, label, id=0,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/stream/", data=json.dumps(dict(from_device=from_device, + to_device=to_device, + label=label, + id=id, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_stream(stream_id, from_device=None, to_device=None, label=None, id=None,): + headers = {'content-type': 'application/json'} + data = dict(from_device=from_device, + to_device=to_device, + label=label, + id=id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/stream/" + str(stream_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_stream(stream_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/stream/" + str(stream_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_process(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/process/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_process(process_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/process/" + str(process_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_process(device, name, type, id=0,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/process/", data=json.dumps(dict(device=device, + name=name, + type=type, + id=id, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_process(process_id, device=None, name=None, type=None, id=None,): + headers = {'content-type': 'application/json'} + data = dict(device=device, + name=name, + type=type, + id=id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/process/" + str(process_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_process(process_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/process/" + str(process_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_toolbox(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/toolbox/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_toolbox(toolbox_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/toolbox/" + str(toolbox_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_toolbox(name,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/toolbox/", data=json.dumps(dict(name=name, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_toolbox(toolbox_id, name=None,): + headers = {'content-type': 'application/json'} + data = dict(name=name, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/toolbox/" + str(toolbox_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_toolbox(toolbox_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/toolbox/" + str(toolbox_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_toolboxitem(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/toolboxitem/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_toolboxitem(toolbox_item_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/toolboxitem/" + str(toolbox_item_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_toolboxitem(toolbox, data,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/toolboxitem/", data=json.dumps(dict(toolbox=toolbox, + data=data, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_toolboxitem(toolbox_item_id, toolbox=None, data=None,): + headers = {'content-type': 'application/json'} + data = dict(toolbox=toolbox, + data=data, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/toolboxitem/" + str(toolbox_item_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_toolboxitem(toolbox_item_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/toolboxitem/" + str(toolbox_item_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_topologyinventory(**kwargs): + response = util.unpaginate(util.get_url(), '/network_ui/api/v1/topologyinventory/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_topologyinventory(topology_inventory_id): + response = requests.get(util.get_url() + "/network_ui/api/v1/topologyinventory/" + + str(topology_inventory_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_topologyinventory(topology, inventory_id,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/network_ui/api/v1/topologyinventory/", data=json.dumps(dict(topology=topology, + inventory_id=inventory_id, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_topologyinventory(topology_inventory_id, topology=None, inventory_id=None,): + headers = {'content-type': 'application/json'} + data = dict(topology=topology, + inventory_id=inventory_id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/network_ui/api/v1/topologyinventory/" + str(topology_inventory_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_topologyinventory(topology_inventory_id): + response = requests.delete(util.get_url() + "/network_ui/api/v1/topologyinventory/" + + str(topology_inventory_id), verify=util.get_verify(), auth=util.get_auth()) + return response diff --git a/awx/network_ui/client/v2_api_client.py b/awx/network_ui/client/v2_api_client.py new file mode 100644 index 0000000000..0544993afe --- /dev/null +++ b/awx/network_ui/client/v2_api_client.py @@ -0,0 +1,500 @@ + +import requests + +import util +import json + + +def list_device(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/device/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_device(device_id): + response = requests.get(util.get_url() + "/api/v2/canvas/device/" + str(device_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_device(topology, name, x, y, id, type, interface_id_seq=0, process_id_seq=0, host_id=0,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/device/", data=json.dumps(dict(topology=topology, + name=name, + x=x, + y=y, + id=id, + type=type, + interface_id_seq=interface_id_seq, + process_id_seq=process_id_seq, + host_id=host_id, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_device(device_id, topology=None, name=None, x=None, y=None, id=None, type=None, interface_id_seq=None, process_id_seq=None, host_id=None,): + headers = {'content-type': 'application/json'} + data = dict(topology=topology, + name=name, + x=x, + y=y, + id=id, + type=type, + interface_id_seq=interface_id_seq, + process_id_seq=process_id_seq, + host_id=host_id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/device/" + str(device_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_device(device_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/device/" + str(device_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_link(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/link/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_link(link_id): + response = requests.get(util.get_url() + "/api/v2/canvas/link/" + str(link_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_link(from_device, to_device, from_interface, to_interface, id, name,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/link/", data=json.dumps(dict(from_device=from_device, + to_device=to_device, + from_interface=from_interface, + to_interface=to_interface, + id=id, + name=name, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_link(link_id, from_device=None, to_device=None, from_interface=None, to_interface=None, id=None, name=None,): + headers = {'content-type': 'application/json'} + data = dict(from_device=from_device, + to_device=to_device, + from_interface=from_interface, + to_interface=to_interface, + id=id, + name=name, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/link/" + str(link_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_link(link_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/link/" + str(link_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_topology(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/topology/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_topology(topology_id): + response = requests.get(util.get_url() + "/api/v2/canvas/topology/" + str(topology_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_topology(name, scale, panX, panY, device_id_seq=0, link_id_seq=0, group_id_seq=0, stream_id_seq=0,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/topology/", data=json.dumps(dict(name=name, + scale=scale, + panX=panX, + panY=panY, + device_id_seq=device_id_seq, + link_id_seq=link_id_seq, + group_id_seq=group_id_seq, + stream_id_seq=stream_id_seq, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_topology(topology_id, name=None, scale=None, panX=None, panY=None, device_id_seq=None, link_id_seq=None, group_id_seq=None, stream_id_seq=None,): + headers = {'content-type': 'application/json'} + data = dict(name=name, + scale=scale, + panX=panX, + panY=panY, + device_id_seq=device_id_seq, + link_id_seq=link_id_seq, + group_id_seq=group_id_seq, + stream_id_seq=stream_id_seq, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/topology/" + str(topology_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_topology(topology_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/topology/" + str(topology_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_interface(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/interface/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_interface(interface_id): + response = requests.get(util.get_url() + "/api/v2/canvas/interface/" + str(interface_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_interface(device, name, id,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/interface/", data=json.dumps(dict(device=device, + name=name, + id=id, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_interface(interface_id, device=None, name=None, id=None,): + headers = {'content-type': 'application/json'} + data = dict(device=device, + name=name, + id=id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/interface/" + str(interface_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_interface(interface_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/interface/" + str(interface_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_group(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/group/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_group(group_id): + response = requests.get(util.get_url() + "/api/v2/canvas/group/" + str(group_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_group(id, name, x1, y1, x2, y2, topology, type,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/group/", data=json.dumps(dict(id=id, + name=name, + x1=x1, + y1=y1, + x2=x2, + y2=y2, + topology=topology, + type=type, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_group(group_id, id=None, name=None, x1=None, y1=None, x2=None, y2=None, topology=None, type=None,): + headers = {'content-type': 'application/json'} + data = dict(id=id, + name=name, + x1=x1, + y1=y1, + x2=x2, + y2=y2, + topology=topology, + type=type, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/group/" + str(group_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_group(group_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/group/" + str(group_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_groupdevice(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/groupdevice/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_groupdevice(group_device_id): + response = requests.get(util.get_url() + "/api/v2/canvas/groupdevice/" + str(group_device_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_groupdevice(group, device,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/groupdevice/", data=json.dumps(dict(group=group, + device=device, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_groupdevice(group_device_id, group=None, device=None,): + headers = {'content-type': 'application/json'} + data = dict(group=group, + device=device, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/groupdevice/" + str(group_device_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_groupdevice(group_device_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/groupdevice/" + str(group_device_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_stream(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/stream/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_stream(stream_id): + response = requests.get(util.get_url() + "/api/v2/canvas/stream/" + str(stream_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_stream(from_device, to_device, label, id=0,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/stream/", data=json.dumps(dict(from_device=from_device, + to_device=to_device, + label=label, + id=id, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_stream(stream_id, from_device=None, to_device=None, label=None, id=None,): + headers = {'content-type': 'application/json'} + data = dict(from_device=from_device, + to_device=to_device, + label=label, + id=id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/stream/" + str(stream_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_stream(stream_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/stream/" + str(stream_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_process(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/process/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_process(process_id): + response = requests.get(util.get_url() + "/api/v2/canvas/process/" + str(process_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_process(device, name, type, id=0,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/process/", data=json.dumps(dict(device=device, + name=name, + type=type, + id=id, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_process(process_id, device=None, name=None, type=None, id=None,): + headers = {'content-type': 'application/json'} + data = dict(device=device, + name=name, + type=type, + id=id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/process/" + str(process_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_process(process_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/process/" + str(process_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_toolbox(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/toolbox/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_toolbox(toolbox_id): + response = requests.get(util.get_url() + "/api/v2/canvas/toolbox/" + str(toolbox_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_toolbox(name,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/toolbox/", data=json.dumps(dict(name=name, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_toolbox(toolbox_id, name=None,): + headers = {'content-type': 'application/json'} + data = dict(name=name, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/toolbox/" + str(toolbox_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_toolbox(toolbox_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/toolbox/" + str(toolbox_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_toolboxitem(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/toolboxitem/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_toolboxitem(toolbox_item_id): + response = requests.get(util.get_url() + "/api/v2/canvas/toolboxitem/" + str(toolbox_item_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_toolboxitem(toolbox, data,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/toolboxitem/", data=json.dumps(dict(toolbox=toolbox, + data=data, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_toolboxitem(toolbox_item_id, toolbox=None, data=None,): + headers = {'content-type': 'application/json'} + data = dict(toolbox=toolbox, + data=data, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/toolboxitem/" + str(toolbox_item_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_toolboxitem(toolbox_item_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/toolboxitem/" + str(toolbox_item_id), verify=util.get_verify(), auth=util.get_auth()) + return response + + +def list_topologyinventory(**kwargs): + response = util.unpaginate(util.get_url(), '/api/v2/canvas/topologyinventory/', util.get_verify(), util.get_auth(), kwargs) + return response + + +def get_topologyinventory(topology_inventory_id): + response = requests.get(util.get_url() + "/api/v2/canvas/topologyinventory/" + str(topology_inventory_id), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + + +def create_topologyinventory(topology, inventory_id,): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "/api/v2/canvas/topologyinventory/", data=json.dumps(dict(topology=topology, + inventory_id=inventory_id, + )), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + + +def update_topologyinventory(topology_inventory_id, topology=None, inventory_id=None,): + headers = {'content-type': 'application/json'} + data = dict(topology=topology, + inventory_id=inventory_id, + ) + data = {x: y for x, y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "/api/v2/canvas/topologyinventory/" + str(topology_inventory_id) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_topologyinventory(topology_inventory_id): + response = requests.delete(util.get_url() + "/api/v2/canvas/topologyinventory/" + + str(topology_inventory_id), verify=util.get_verify(), auth=util.get_auth()) + return response diff --git a/awx/network_ui/designs/api.yml b/awx/network_ui/designs/api.yml new file mode 100644 index 0000000000..006890a1c6 --- /dev/null +++ b/awx/network_ui/designs/api.yml @@ -0,0 +1,66 @@ +models: +- name: Device + api: true + v1_end_point: /network_ui/api/v1/device/ + v2_end_point: /api/v2/canvas/device/ + topology_id_query: topology_id + v2_lookup_field: host_id +- name: Link + api: true + v1_end_point: /network_ui/api/v1/link/ + v2_end_point: /api/v2/canvas/link/ + topology_id_query: from_device__topology_id + create_transform: + id: id + name: name + from_device__id: from_device_id + from_interface__id: from_interface_id + to_device__id: to_device_id + to_interface__id: to_interface_id +- name: Interface + api: true + v1_end_point: /network_ui/api/v1/interface/ + v2_end_point: /api/v2/canvas/interface/ + topology_id_query: device__topology_id + create_transform: + id: id + name: name + device__id: device_id +- name: Group + api: true + v1_end_point: /network_ui/api/v1/group/ + v2_end_point: /api/v2/canvas/group/ + topology_id_query: topology_id +- name: GroupDevice + api: true + v1_end_point: /network_ui/api/v1/groupdevice/ + v2_end_point: /api/v2/canvas/groupdevice/ + topology_id_query: group__topology_id +- name: Topology + api: true + v1_end_point: /network_ui/api/v1/topology/ + v2_end_point: /api/v2/canvas/topology/ + topology_id_query: topology_id +- name: TopologyInventory + api: true + v1_end_point: /network_ui/api/v1/topologyinventory/ + v2_end_point: /api/v2/canvas/topologyinventory/ + topology_id_query: topology_id +- name: Toolbox + api: true + v1_end_point: /network_ui/api/v1/toolbox/ + v2_end_point: /api/v2/canvas/toolbox/ +- name: ToolboxItem + api: true + v1_end_point: /network_ui/api/v1/toolboxitem/ + v2_end_point: /api/v2/canvas/toolboxitem/ +- name: Stream + api: true + v1_end_point: /network_ui/api/v1/stream/ + v2_end_point: /api/v2/canvas/stream/ + topology_id_query: from_device__topology_id +- name: Process + api: true + v1_end_point: /network_ui/api/v1/process/ + v2_end_point: /api/v2/canvas/process/ + topology_id_query: device__topology_id diff --git a/awx/network_ui/designs/merge_design.py b/awx/network_ui/designs/merge_design.py new file mode 100755 index 0000000000..7ea6e80bcc --- /dev/null +++ b/awx/network_ui/designs/merge_design.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Usage: + merge_yaml [options] + +Options: + -h, --help Show this page + --debug Show debug logging + --verbose Show verbose logging +""" +from docopt import docopt +import logging +import sys +import yaml + +logger = logging.getLogger('merge_yaml') + + +def main(args=None): + if args is None: + args = sys.argv[1:] + parsed_args = docopt(__doc__, args) + if parsed_args['--debug']: + logging.basicConfig(level=logging.DEBUG) + elif parsed_args['--verbose']: + logging.basicConfig(level=logging.INFO) + else: + logging.basicConfig(level=logging.WARNING) + + with open(parsed_args['']) as f: + a = yaml.load(f.read()) + with open(parsed_args['']) as f: + b = yaml.load(f.read()) + + a_models = {x['name']: x for x in a.get('models', [])} + for model in b.get('models', []): + for key, value in model.iteritems(): + a_models[model['name']][key] = value + + + print (yaml.safe_dump(a, default_flow_style=False)) + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) + diff --git a/awx/network_ui/designs/models.yml b/awx/network_ui/designs/models.yml index e204679670..140d5bdd46 100644 --- a/awx/network_ui/designs/models.yml +++ b/awx/network_ui/designs/models.yml @@ -1,7 +1,9 @@ app: awx.network_ui external_models: [] models: -- display: name +- api: true + display: name + end_point: /network_ui/api/v1/device/ fields: - name: device_id pk: true @@ -32,9 +34,21 @@ models: name: host_id type: IntegerField name: Device + topology_id_query: topology_id + v1_end_point: /network_ui/api/v1/device/ + v2_end_point: /api/v2/canvas/device/ + v2_lookup_field: host_id x: 348 y: 124 -- fields: +- api: true + create_transform: + from_device__id: from_device_id + from_interface__id: from_interface_id + id: id + name: name + to_device__id: to_device_id + to_interface__id: to_interface_id + fields: - name: link_id pk: true type: AutoField @@ -64,9 +78,14 @@ models: name: name type: CharField name: Link + topology_id_query: from_device__topology_id + v1_end_point: /network_ui/api/v1/link/ + v2_end_point: /api/v2/canvas/link/ x: 837 y: 10 -- display: name +- api: true + display: name + end_point: /network_ui/api/v1/topology/ fields: - name: topology_id pk: true @@ -88,13 +107,14 @@ models: type: IntegerField - default: 0 name: group_id_seq - ref: Topology - ref_field: group_id_seq type: IntegerField - default: 0 name: stream_id_seq type: IntegerField name: Topology + topology_id_query: topology_id + v1_end_point: /network_ui/api/v1/topology/ + v2_end_point: /api/v2/canvas/topology/ x: 111 y: 127 - fields: @@ -141,7 +161,13 @@ models: name: MessageType x: -501 y: 428 -- display: name +- api: true + create_transform: + device__id: device_id + id: id + name: name + display: name + end_point: /network_ui/api/v1/interface/ fields: - name: interface_id pk: true @@ -156,9 +182,14 @@ models: - name: id type: IntegerField name: Interface + topology_id_query: device__topology_id + v1_end_point: /network_ui/api/v1/interface/ + v2_end_point: /api/v2/canvas/interface/ x: 1157 y: 337 -- fields: +- api: true + end_point: /network_ui/api/v1/group/ + fields: - name: group_id pk: true type: AutoField @@ -183,9 +214,14 @@ models: name: type type: CharField name: Group + topology_id_query: topology_id + v1_end_point: /network_ui/api/v1/group/ + v2_end_point: /api/v2/canvas/group/ x: 407 y: -379 -- fields: +- api: true + end_point: /network_ui/api/v1/groupdevice/ + fields: - name: group_device_id pk: true type: AutoField @@ -198,6 +234,9 @@ models: ref_field: device_id type: ForeignKey name: GroupDevice + topology_id_query: group__topology_id + v1_end_point: /network_ui/api/v1/groupdevice/ + v2_end_point: /api/v2/canvas/groupdevice/ x: 739 y: -234 - fields: @@ -255,7 +294,9 @@ models: name: DataSheet x: -207 y: -282 -- fields: +- api: true + end_point: /network_ui/api/v1/stream/ + fields: - name: stream_id pk: true ref: Stream @@ -278,9 +319,14 @@ models: name: id type: IntegerField name: Stream + topology_id_query: from_device__topology_id + v1_end_point: /network_ui/api/v1/stream/ + v2_end_point: /api/v2/canvas/stream/ x: 709 y: 527 -- fields: +- api: true + end_point: /network_ui/api/v1/process/ + fields: - name: process_id pk: true type: AutoField @@ -298,9 +344,14 @@ models: name: id type: IntegerField name: Process + topology_id_query: device__topology_id + v1_end_point: /network_ui/api/v1/process/ + v2_end_point: /api/v2/canvas/process/ x: 654 y: 778 -- fields: +- api: true + end_point: /network_ui/api/v1/toolbox/ + fields: - name: toolbox_id pk: true type: AutoField @@ -308,9 +359,13 @@ models: name: name type: CharField name: Toolbox + v1_end_point: /network_ui/api/v1/toolbox/ + v2_end_point: /api/v2/canvas/toolbox/ x: 179 y: 644 -- fields: +- api: true + end_point: /network_ui/api/v1/toolboxitem/ + fields: - name: toolbox_item_id pk: true type: AutoField @@ -321,6 +376,8 @@ models: - name: data type: TextField name: ToolboxItem + v1_end_point: /network_ui/api/v1/toolboxitem/ + v2_end_point: /api/v2/canvas/toolboxitem/ x: 391 y: 645 - fields: @@ -352,7 +409,9 @@ models: name: FSMTrace x: -872 y: 507 -- fields: +- api: true + end_point: /network_ui/api/v1/topologyinventory/ + fields: - name: topology_inventory_id pk: true type: AutoField @@ -363,6 +422,9 @@ models: - name: inventory_id type: IntegerField name: TopologyInventory + topology_id_query: topology_id + v1_end_point: /network_ui/api/v1/topologyinventory/ + v2_end_point: /api/v2/canvas/topologyinventory/ x: -226 y: -19 - fields: @@ -494,3 +556,4 @@ view: panX: 213.729555519212 panY: 189.446959094643 scaleXY: 0.69 + diff --git a/awx/network_ui/designs/new.yml b/awx/network_ui/designs/new.yml new file mode 100644 index 0000000000..5a9d7b6a5d --- /dev/null +++ b/awx/network_ui/designs/new.yml @@ -0,0 +1,526 @@ +app: awx.network_ui +external_models: [] +models: +- api: true + display: name + fields: + - name: device_id + pk: true + type: AutoField + - name: topology + ref: Topology + ref_field: topology_id + type: ForeignKey + - len: 200 + name: name + type: CharField + - name: x + type: IntegerField + - name: y + type: IntegerField + - name: id + type: IntegerField + - len: 200 + name: type + type: CharField + - default: 0 + name: interface_id_seq + type: IntegerField + - default: 0 + name: process_id_seq + type: IntegerField + - default: 0 + name: host_id + type: IntegerField + name: Device + topology_id_query: topology_id + x: 348 + y: 124 +- api: true + create_transform: + from_device__id: from_device_id + from_interface__id: from_interface_id + id: id + name: name + to_device__id: to_device_id + to_interface__id: to_interface_id + fields: + - name: link_id + pk: true + type: AutoField + - name: from_device + ref: Device + ref_field: device_id + related_name: from_link + type: ForeignKey + - name: to_device + ref: Device + ref_field: device_id + related_name: to_link + type: ForeignKey + - name: from_interface + ref: Interface + ref_field: interface_id + related_name: from_link + type: ForeignKey + - name: to_interface + ref: Interface + ref_field: interface_id + related_name: to_link + type: ForeignKey + - name: id + type: IntegerField + - len: 200 + name: name + type: CharField + name: Link + topology_id_query: from_device__topology_id + x: 837 + y: 10 +- api: true + display: name + fields: + - name: topology_id + pk: true + type: AutoField + - len: 200 + name: name + type: CharField + - name: scale + type: FloatField + - name: panX + type: FloatField + - name: panY + type: FloatField + - default: 0 + name: device_id_seq + type: IntegerField + - default: 0 + name: link_id_seq + type: IntegerField + - default: 0 + name: group_id_seq + type: IntegerField + - default: 0 + name: stream_id_seq + type: IntegerField + name: Topology + topology_id_query: topology_id + x: 111 + y: 127 +- fields: + - name: client_id + pk: true + type: AutoField + name: Client + x: -518 + y: 138 +- fields: + - name: topology_history_id + pk: true + type: AutoField + - name: topology + ref: Topology + ref_field: topology_id + type: ForeignKey + - name: client + ref: Client + ref_field: client_id + type: ForeignKey + - name: message_type + ref: MessageType + ref_field: message_type_id + type: ForeignKey + - name: message_id + type: IntegerField + - name: message_data + type: TextField + - default: false + name: undone + type: BooleanField + name: TopologyHistory + x: -205 + y: 282 +- display: name + fields: + - name: message_type_id + pk: true + type: AutoField + - len: 200 + name: name + type: CharField + name: MessageType + x: -501 + y: 428 +- api: true + create_transform: + device__id: device_id + id: id + name: name + display: name + fields: + - name: interface_id + pk: true + type: AutoField + - name: device + ref: Device + ref_field: device_id + type: ForeignKey + - len: 200 + name: name + type: CharField + - name: id + type: IntegerField + name: Interface + topology_id_query: device__topology_id + x: 1157 + y: 337 +- api: true + fields: + - name: group_id + pk: true + type: AutoField + - name: id + type: IntegerField + - len: 200 + name: name + type: CharField + - name: x1 + type: IntegerField + - name: y1 + type: IntegerField + - name: x2 + type: IntegerField + - name: y2 + type: IntegerField + - name: topology + ref: Topology + ref_field: topology_id + type: ForeignKey + - len: 200 + name: type + type: CharField + name: Group + topology_id_query: topology_id + x: 407 + y: -379 +- api: true + fields: + - name: group_device_id + pk: true + type: AutoField + - name: group + ref: Group + ref_field: group_id + type: ForeignKey + - name: device + ref: Device + ref_field: device_id + type: ForeignKey + name: GroupDevice + topology_id_query: group__topology_id + x: 739 + y: -234 +- fields: + - name: data_binding_id + pk: true + type: AutoField + - name: column + type: IntegerField + - name: row + type: IntegerField + - len: 200 + name: table + type: CharField + - name: primary_key_id + type: IntegerField + - len: 200 + name: field + type: CharField + - name: data_type + ref: DataType + ref_field: data_type_id + type: ForeignKey + - name: sheet + ref: DataSheet + ref_field: data_sheet_id + type: ForeignKey + name: DataBinding + x: -515 + y: -370 +- fields: + - name: data_type_id + pk: true + type: AutoField + - len: 200 + name: type_name + type: CharField + name: DataType + x: -782 + y: -172 +- fields: + - name: data_sheet_id + pk: true + type: AutoField + - len: 200 + name: name + type: CharField + - name: topology + ref: Topology + ref_field: topology_id + type: ForeignKey + - name: client + ref: Client + ref_field: client_id + type: ForeignKey + name: DataSheet + x: -207 + y: -282 +- api: true + fields: + - name: stream_id + pk: true + ref: Stream + ref_field: stream_id + type: AutoField + - name: from_device + ref: Device + ref_field: device_id + related_name: from_stream + type: ForeignKey + - name: to_device + ref: Device + ref_field: device_id + related_name: to_stream + type: ForeignKey + - len: 200 + name: label + type: CharField + - default: 0 + name: id + type: IntegerField + name: Stream + topology_id_query: from_device__topology_id + x: 709 + y: 527 +- api: true + fields: + - name: process_id + pk: true + type: AutoField + - name: device + ref: Device + ref_field: device_id + type: ForeignKey + - len: 200 + name: name + type: CharField + - len: 200 + name: type + type: CharField + - default: 0 + name: id + type: IntegerField + name: Process + topology_id_query: device__topology_id + x: 654 + y: 778 +- api: true + fields: + - name: toolbox_id + pk: true + type: AutoField + - len: 200 + name: name + type: CharField + name: Toolbox + x: 179 + y: 644 +- api: true + fields: + - name: toolbox_item_id + pk: true + type: AutoField + - name: toolbox + ref: Toolbox + ref_field: toolbox_id + type: ForeignKey + - name: data + type: TextField + name: ToolboxItem + x: 391 + y: 645 +- fields: + - name: fsm_trace_id + pk: true + type: AutoField + - len: 200 + name: fsm_name + type: CharField + - len: 200 + name: from_state + type: CharField + - len: 200 + name: to_state + type: CharField + - len: 200 + name: message_type + type: CharField + - name: client + ref: Client + ref_field: client_id + type: ForeignKey + - default: 0 + name: trace_session_id + type: IntegerField + - default: 0 + name: order + type: IntegerField + name: FSMTrace + x: -872 + y: 507 +- api: true + fields: + - name: topology_inventory_id + pk: true + type: AutoField + - name: topology + ref: Topology + ref_field: topology_id + type: ForeignKey + - name: inventory_id + type: IntegerField + name: TopologyInventory + topology_id_query: topology_id + x: -226 + y: -19 +- fields: + - name: event_trace_id + pk: true + type: AutoField + - name: client + ref: Client + ref_field: client_id + type: ForeignKey + - default: 0 + name: trace_session_id + type: IntegerField + - name: event_data + type: TextField + - name: message_id + type: IntegerField + name: EventTrace + x: -1087 + y: 202 +- fields: + - name: coverage_id + pk: true + type: AutoField + - name: coverage_data + type: TextField + - name: test_result + ref: TestResult + ref_field: test_result_id + type: ForeignKey + name: Coverage + x: -1068 + y: -4 +- fields: + - name: topology_snapshot_id + pk: true + type: AutoField + - name: client + ref: Client + ref_field: client_id + type: ForeignKey + - name: topology_id + type: IntegerField + - name: trace_session_id + type: IntegerField + - name: snapshot_data + ref: TopologySnapshot + ref_field: snapshot_data + type: TextField + - name: order + type: IntegerField + name: TopologySnapshot + x: -1123 + y: -277 +- fields: + - name: test_case_id + pk: true + type: AutoField + - len: 200 + name: name + ref: TestCase + ref_field: name + type: CharField + - name: test_case_data + type: TextField + name: TestCase + x: -1642 + y: -38 +- fields: + - name: result_id + pk: true + type: AutoField + - len: 20 + name: name + type: CharField + name: Result + x: -1610 + y: 120 +- fields: + - name: code_under_test_id + pk: true + ref: CodeUnderTest + ref_field: code_under_test_id + type: AutoField + - name: version_x + type: IntegerField + - name: version_y + type: IntegerField + - name: version_z + type: IntegerField + - name: commits_since + type: IntegerField + - len: 40 + name: commit_hash + type: CharField + name: CodeUnderTest + x: -1612 + y: 259 +- fields: + - name: test_result_id + pk: true + type: AutoField + - name: test_case + ref: TestCase + ref_field: test_case_id + type: ForeignKey + - name: result + ref: Result + ref_field: result_id + type: ForeignKey + - name: code_under_test + ref: CodeUnderTest + ref_field: code_under_test_id + type: ForeignKey + - name: time + type: DateTimeField + - default: 0 + name: id + type: IntegerField + - name: client + ref: Client + ref_field: client_id + type: ForeignKey + name: TestResult + x: -1336 + y: -49 +modules: [] +view: + panX: 213.729555519212 + panY: 189.446959094643 + scaleXY: 0.69 + diff --git a/awx/network_ui/library/create_device.py b/awx/network_ui/library/create_device.py new file mode 100644 index 0000000000..34f7792833 --- /dev/null +++ b/awx/network_ui/library/create_device.py @@ -0,0 +1 @@ +#---- create_device diff --git a/awx/network_ui/library/create_group.py b/awx/network_ui/library/create_group.py new file mode 100644 index 0000000000..09c27c2ee9 --- /dev/null +++ b/awx/network_ui/library/create_group.py @@ -0,0 +1 @@ +#---- create_group diff --git a/awx/network_ui/library/create_groupdevice.py b/awx/network_ui/library/create_groupdevice.py new file mode 100644 index 0000000000..dd266b3637 --- /dev/null +++ b/awx/network_ui/library/create_groupdevice.py @@ -0,0 +1 @@ +#---- create_groupdevice diff --git a/awx/network_ui/library/create_interface.py b/awx/network_ui/library/create_interface.py new file mode 100644 index 0000000000..5a70ff6b9c --- /dev/null +++ b/awx/network_ui/library/create_interface.py @@ -0,0 +1 @@ +#---- create_interface diff --git a/awx/network_ui/library/create_link.py b/awx/network_ui/library/create_link.py new file mode 100644 index 0000000000..ed86ae23fb --- /dev/null +++ b/awx/network_ui/library/create_link.py @@ -0,0 +1 @@ +#---- create_link diff --git a/awx/network_ui/library/create_process.py b/awx/network_ui/library/create_process.py new file mode 100644 index 0000000000..7067949e65 --- /dev/null +++ b/awx/network_ui/library/create_process.py @@ -0,0 +1 @@ +#---- create_process diff --git a/awx/network_ui/library/create_stream.py b/awx/network_ui/library/create_stream.py new file mode 100644 index 0000000000..a0ada8530e --- /dev/null +++ b/awx/network_ui/library/create_stream.py @@ -0,0 +1 @@ +#---- create_stream diff --git a/awx/network_ui/library/create_toolbox.py b/awx/network_ui/library/create_toolbox.py new file mode 100644 index 0000000000..badd71fd8f --- /dev/null +++ b/awx/network_ui/library/create_toolbox.py @@ -0,0 +1 @@ +#---- create_toolbox diff --git a/awx/network_ui/library/create_toolboxitem.py b/awx/network_ui/library/create_toolboxitem.py new file mode 100644 index 0000000000..64461a9658 --- /dev/null +++ b/awx/network_ui/library/create_toolboxitem.py @@ -0,0 +1 @@ +#---- create_toolboxitem diff --git a/awx/network_ui/library/create_topology.py b/awx/network_ui/library/create_topology.py new file mode 100644 index 0000000000..a97827f3ef --- /dev/null +++ b/awx/network_ui/library/create_topology.py @@ -0,0 +1 @@ +#---- create_topology diff --git a/awx/network_ui/library/create_topologyinventory.py b/awx/network_ui/library/create_topologyinventory.py new file mode 100644 index 0000000000..645fa571de --- /dev/null +++ b/awx/network_ui/library/create_topologyinventory.py @@ -0,0 +1 @@ +#---- create_topologyinventory diff --git a/awx/network_ui/library/delete_device.py b/awx/network_ui/library/delete_device.py new file mode 100644 index 0000000000..103053cc00 --- /dev/null +++ b/awx/network_ui/library/delete_device.py @@ -0,0 +1 @@ +#---- delete_device diff --git a/awx/network_ui/library/delete_group.py b/awx/network_ui/library/delete_group.py new file mode 100644 index 0000000000..eba6b41a34 --- /dev/null +++ b/awx/network_ui/library/delete_group.py @@ -0,0 +1 @@ +#---- delete_group diff --git a/awx/network_ui/library/delete_groupdevice.py b/awx/network_ui/library/delete_groupdevice.py new file mode 100644 index 0000000000..6feed31553 --- /dev/null +++ b/awx/network_ui/library/delete_groupdevice.py @@ -0,0 +1 @@ +#---- delete_groupdevice diff --git a/awx/network_ui/library/delete_interface.py b/awx/network_ui/library/delete_interface.py new file mode 100644 index 0000000000..900738e244 --- /dev/null +++ b/awx/network_ui/library/delete_interface.py @@ -0,0 +1 @@ +#---- delete_interface diff --git a/awx/network_ui/library/delete_link.py b/awx/network_ui/library/delete_link.py new file mode 100644 index 0000000000..7f4652a096 --- /dev/null +++ b/awx/network_ui/library/delete_link.py @@ -0,0 +1 @@ +#---- delete_link diff --git a/awx/network_ui/library/delete_process.py b/awx/network_ui/library/delete_process.py new file mode 100644 index 0000000000..660d99ccd6 --- /dev/null +++ b/awx/network_ui/library/delete_process.py @@ -0,0 +1 @@ +#---- delete_process diff --git a/awx/network_ui/library/delete_stream.py b/awx/network_ui/library/delete_stream.py new file mode 100644 index 0000000000..f0ed0d38b6 --- /dev/null +++ b/awx/network_ui/library/delete_stream.py @@ -0,0 +1 @@ +#---- delete_stream diff --git a/awx/network_ui/library/delete_toolbox.py b/awx/network_ui/library/delete_toolbox.py new file mode 100644 index 0000000000..692cfdfd92 --- /dev/null +++ b/awx/network_ui/library/delete_toolbox.py @@ -0,0 +1 @@ +#---- delete_toolbox diff --git a/awx/network_ui/library/delete_toolboxitem.py b/awx/network_ui/library/delete_toolboxitem.py new file mode 100644 index 0000000000..3c563f6fde --- /dev/null +++ b/awx/network_ui/library/delete_toolboxitem.py @@ -0,0 +1 @@ +#---- delete_toolboxitem diff --git a/awx/network_ui/library/delete_topology.py b/awx/network_ui/library/delete_topology.py new file mode 100644 index 0000000000..c03c00ab8e --- /dev/null +++ b/awx/network_ui/library/delete_topology.py @@ -0,0 +1 @@ +#---- delete_topology diff --git a/awx/network_ui/library/delete_topologyinventory.py b/awx/network_ui/library/delete_topologyinventory.py new file mode 100644 index 0000000000..122e2d9308 --- /dev/null +++ b/awx/network_ui/library/delete_topologyinventory.py @@ -0,0 +1 @@ +#---- delete_topologyinventory diff --git a/awx/network_ui/library/get_device.py b/awx/network_ui/library/get_device.py new file mode 100644 index 0000000000..f20d5e382a --- /dev/null +++ b/awx/network_ui/library/get_device.py @@ -0,0 +1 @@ +#---- get_device diff --git a/awx/network_ui/library/get_group.py b/awx/network_ui/library/get_group.py new file mode 100644 index 0000000000..13a90acc49 --- /dev/null +++ b/awx/network_ui/library/get_group.py @@ -0,0 +1 @@ +#---- get_group diff --git a/awx/network_ui/library/get_groupdevice.py b/awx/network_ui/library/get_groupdevice.py new file mode 100644 index 0000000000..a363cae561 --- /dev/null +++ b/awx/network_ui/library/get_groupdevice.py @@ -0,0 +1 @@ +#---- get_groupdevice diff --git a/awx/network_ui/library/get_interface.py b/awx/network_ui/library/get_interface.py new file mode 100644 index 0000000000..4a87baec12 --- /dev/null +++ b/awx/network_ui/library/get_interface.py @@ -0,0 +1 @@ +#---- get_interface diff --git a/awx/network_ui/library/get_link.py b/awx/network_ui/library/get_link.py new file mode 100644 index 0000000000..ba23e6ee22 --- /dev/null +++ b/awx/network_ui/library/get_link.py @@ -0,0 +1 @@ +#---- get_link diff --git a/awx/network_ui/library/get_process.py b/awx/network_ui/library/get_process.py new file mode 100644 index 0000000000..9d1114800a --- /dev/null +++ b/awx/network_ui/library/get_process.py @@ -0,0 +1 @@ +#---- get_process diff --git a/awx/network_ui/library/get_stream.py b/awx/network_ui/library/get_stream.py new file mode 100644 index 0000000000..9fac49ea69 --- /dev/null +++ b/awx/network_ui/library/get_stream.py @@ -0,0 +1 @@ +#---- get_stream diff --git a/awx/network_ui/library/get_toolbox.py b/awx/network_ui/library/get_toolbox.py new file mode 100644 index 0000000000..49de524e87 --- /dev/null +++ b/awx/network_ui/library/get_toolbox.py @@ -0,0 +1 @@ +#---- get_toolbox diff --git a/awx/network_ui/library/get_toolboxitem.py b/awx/network_ui/library/get_toolboxitem.py new file mode 100644 index 0000000000..902ab5f3b3 --- /dev/null +++ b/awx/network_ui/library/get_toolboxitem.py @@ -0,0 +1 @@ +#---- get_toolboxitem diff --git a/awx/network_ui/library/get_topology.py b/awx/network_ui/library/get_topology.py new file mode 100644 index 0000000000..39e2001122 --- /dev/null +++ b/awx/network_ui/library/get_topology.py @@ -0,0 +1 @@ +#---- get_topology diff --git a/awx/network_ui/library/get_topologyinventory.py b/awx/network_ui/library/get_topologyinventory.py new file mode 100644 index 0000000000..29bc467319 --- /dev/null +++ b/awx/network_ui/library/get_topologyinventory.py @@ -0,0 +1 @@ +#---- get_topologyinventory diff --git a/awx/network_ui/library/list_device.py b/awx/network_ui/library/list_device.py new file mode 100644 index 0000000000..4aab317163 --- /dev/null +++ b/awx/network_ui/library/list_device.py @@ -0,0 +1 @@ +#---- list_device diff --git a/awx/network_ui/library/list_group.py b/awx/network_ui/library/list_group.py new file mode 100644 index 0000000000..64bc2eaa16 --- /dev/null +++ b/awx/network_ui/library/list_group.py @@ -0,0 +1 @@ +#---- list_group diff --git a/awx/network_ui/library/list_groupdevice.py b/awx/network_ui/library/list_groupdevice.py new file mode 100644 index 0000000000..ba64ddd645 --- /dev/null +++ b/awx/network_ui/library/list_groupdevice.py @@ -0,0 +1 @@ +#---- list_groupdevice diff --git a/awx/network_ui/library/list_interface.py b/awx/network_ui/library/list_interface.py new file mode 100644 index 0000000000..cb99605c21 --- /dev/null +++ b/awx/network_ui/library/list_interface.py @@ -0,0 +1 @@ +#---- list_interface diff --git a/awx/network_ui/library/list_link.py b/awx/network_ui/library/list_link.py new file mode 100644 index 0000000000..d2eae1db34 --- /dev/null +++ b/awx/network_ui/library/list_link.py @@ -0,0 +1 @@ +#---- list_link diff --git a/awx/network_ui/library/list_process.py b/awx/network_ui/library/list_process.py new file mode 100644 index 0000000000..9937b17745 --- /dev/null +++ b/awx/network_ui/library/list_process.py @@ -0,0 +1 @@ +#---- list_process diff --git a/awx/network_ui/library/list_stream.py b/awx/network_ui/library/list_stream.py new file mode 100644 index 0000000000..877916333d --- /dev/null +++ b/awx/network_ui/library/list_stream.py @@ -0,0 +1 @@ +#---- list_stream diff --git a/awx/network_ui/library/list_toolbox.py b/awx/network_ui/library/list_toolbox.py new file mode 100644 index 0000000000..7300e93a6a --- /dev/null +++ b/awx/network_ui/library/list_toolbox.py @@ -0,0 +1 @@ +#---- list_toolbox diff --git a/awx/network_ui/library/list_toolboxitem.py b/awx/network_ui/library/list_toolboxitem.py new file mode 100644 index 0000000000..c3fcaf76f7 --- /dev/null +++ b/awx/network_ui/library/list_toolboxitem.py @@ -0,0 +1 @@ +#---- list_toolboxitem diff --git a/awx/network_ui/library/list_topology.py b/awx/network_ui/library/list_topology.py new file mode 100644 index 0000000000..67cba0597b --- /dev/null +++ b/awx/network_ui/library/list_topology.py @@ -0,0 +1 @@ +#---- list_topology diff --git a/awx/network_ui/library/list_topologyinventory.py b/awx/network_ui/library/list_topologyinventory.py new file mode 100644 index 0000000000..28d71c5238 --- /dev/null +++ b/awx/network_ui/library/list_topologyinventory.py @@ -0,0 +1 @@ +#---- list_topologyinventory diff --git a/awx/network_ui/library/update_device.py b/awx/network_ui/library/update_device.py new file mode 100644 index 0000000000..5de28bc420 --- /dev/null +++ b/awx/network_ui/library/update_device.py @@ -0,0 +1 @@ +#---- update_device diff --git a/awx/network_ui/library/update_group.py b/awx/network_ui/library/update_group.py new file mode 100644 index 0000000000..7e0ee1a677 --- /dev/null +++ b/awx/network_ui/library/update_group.py @@ -0,0 +1 @@ +#---- update_group diff --git a/awx/network_ui/library/update_groupdevice.py b/awx/network_ui/library/update_groupdevice.py new file mode 100644 index 0000000000..8344403589 --- /dev/null +++ b/awx/network_ui/library/update_groupdevice.py @@ -0,0 +1 @@ +#---- update_groupdevice diff --git a/awx/network_ui/library/update_interface.py b/awx/network_ui/library/update_interface.py new file mode 100644 index 0000000000..d5460ceccc --- /dev/null +++ b/awx/network_ui/library/update_interface.py @@ -0,0 +1 @@ +#---- update_interface diff --git a/awx/network_ui/library/update_link.py b/awx/network_ui/library/update_link.py new file mode 100644 index 0000000000..a37cebd2a3 --- /dev/null +++ b/awx/network_ui/library/update_link.py @@ -0,0 +1 @@ +#---- update_link diff --git a/awx/network_ui/library/update_process.py b/awx/network_ui/library/update_process.py new file mode 100644 index 0000000000..6d26267aa2 --- /dev/null +++ b/awx/network_ui/library/update_process.py @@ -0,0 +1 @@ +#---- update_process diff --git a/awx/network_ui/library/update_stream.py b/awx/network_ui/library/update_stream.py new file mode 100644 index 0000000000..1563ab1d4b --- /dev/null +++ b/awx/network_ui/library/update_stream.py @@ -0,0 +1 @@ +#---- update_stream diff --git a/awx/network_ui/library/update_toolbox.py b/awx/network_ui/library/update_toolbox.py new file mode 100644 index 0000000000..8d493f9f71 --- /dev/null +++ b/awx/network_ui/library/update_toolbox.py @@ -0,0 +1 @@ +#---- update_toolbox diff --git a/awx/network_ui/library/update_toolboxitem.py b/awx/network_ui/library/update_toolboxitem.py new file mode 100644 index 0000000000..b9d900160c --- /dev/null +++ b/awx/network_ui/library/update_toolboxitem.py @@ -0,0 +1 @@ +#---- update_toolboxitem diff --git a/awx/network_ui/library/update_topology.py b/awx/network_ui/library/update_topology.py new file mode 100644 index 0000000000..53cfef06e9 --- /dev/null +++ b/awx/network_ui/library/update_topology.py @@ -0,0 +1 @@ +#---- update_topology diff --git a/awx/network_ui/library/update_topologyinventory.py b/awx/network_ui/library/update_topologyinventory.py new file mode 100644 index 0000000000..09f7956ebc --- /dev/null +++ b/awx/network_ui/library/update_topologyinventory.py @@ -0,0 +1 @@ +#---- update_topologyinventory diff --git a/awx/network_ui/models.py b/awx/network_ui/models.py index c18159cc97..0f9120ad6c 100644 --- a/awx/network_ui/models.py +++ b/awx/network_ui/models.py @@ -38,7 +38,7 @@ class Topology(models.Model): panY = models.FloatField() device_id_seq = models.IntegerField(default=0) link_id_seq = models.IntegerField(default=0) - group_id_seq = models.IntegerField('Topology', default=0) + group_id_seq = models.IntegerField(default=0) stream_id_seq = models.IntegerField(default=0) def __unicode__(self): diff --git a/awx/network_ui/templates/action_plugins/create_model.pyt b/awx/network_ui/templates/action_plugins/create_model.pyt new file mode 100644 index 0000000000..db0325634b --- /dev/null +++ b/awx/network_ui/templates/action_plugins/create_model.pyt @@ -0,0 +1,51 @@ +{%for model in models-%} +{%-if model.api-%} +#---- create_{{model.name.lower()}} + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + the_list = self._task.args.get('list', None) + list_var = self._task.args.get('list_var', None) +{%for field in model.fields%}{%if not field.pk and field.default is not defined%} + {{field.name}} = self._task.args.get('{{field.name}}', None){%endif%}{%endfor%} +{%for field in model.fields%}{%if not field.pk and field.default is defined%} + {{field.name}} = self._task.args.get('{{field.name}}', {{field.default}}){%endif%}{%endfor%} + + url = server + '{{model.v2_end_point}}' + headers = {'content-type': 'application/json'} + response = requests.post(url, data=json.dumps(dict({%for field in model.fields%}{%if not field.pk%}{{field.name}}={{field.name}}, + {%endif%}{%endfor%})), + verify=False, + auth=(user, password), + headers=headers) + if var is not None: + result['ansible_facts'] = {var: response.json()} + elif list_var is not None: + if the_list is None: + the_list = [] + the_list.append(response.json()) + result['ansible_facts'] = {list_var: the_list} + return result + +{%endif%} +{%endfor%} diff --git a/awx/network_ui/templates/action_plugins/delete_model.pyt b/awx/network_ui/templates/action_plugins/delete_model.pyt new file mode 100644 index 0000000000..1a9b6098c7 --- /dev/null +++ b/awx/network_ui/templates/action_plugins/delete_model.pyt @@ -0,0 +1,35 @@ +{%for model in models-%} +{%-if model.api-%} +#---- delete_{{model.name.lower()}} + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + +{%for field in model.fields%}{%if field.pk%} + {{field.name}} = self._task.args.get('{{field.name}}', None){%endif%}{%endfor%} + + url = server + '{{model.v2_end_point}}' + str({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}) + '/' + requests.delete(url, + verify=False, + auth=(user, password)) + return result + +{%endif%} +{%endfor%} diff --git a/awx/network_ui/templates/action_plugins/get_model.pyt b/awx/network_ui/templates/action_plugins/get_model.pyt new file mode 100644 index 0000000000..72e9baf1db --- /dev/null +++ b/awx/network_ui/templates/action_plugins/get_model.pyt @@ -0,0 +1,37 @@ +{%for model in models-%} +{%-if model.api-%} +#---- get_{{model.name.lower()}} + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) +{%for field in model.fields%}{%if field.pk%} + {{field.name}} = self._task.args.get('{{field.name}}', None){%endif%}{%endfor%} + + url = server + '{{model.v2_end_point}}' + str({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}) + '/' + response = requests.get(url, + verify=False, + auth=(user, password)) + result['ansible_facts'] = {var: response.json()} + return result + +{%endif%} +{%endfor%} diff --git a/awx/network_ui/templates/action_plugins/list_model.pyt b/awx/network_ui/templates/action_plugins/list_model.pyt new file mode 100644 index 0000000000..5e1374ec0c --- /dev/null +++ b/awx/network_ui/templates/action_plugins/list_model.pyt @@ -0,0 +1,45 @@ +{%for model in models-%} +{%-if model.api-%} +#---- list_{{model.name.lower()}} + +from ansible.plugins.action import ActionBase + +import requests + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) + +{%for field in model.fields%} + {{field.name}} = self._task.args.get('{{field.name}}', None){%endfor%} + + filter_data=dict({%for field in model.fields%}{{field.name}}={{field.name}}, + {%endfor%}) + filter_data={x:y for x,y in filter_data.iteritems() if y is not None} + + url = '{{model.v2_end_point}}' + results = [] + while url is not None: + url = server + url + data = requests.get(url, verify=False, auth=(user, password), params=filter_data).json() + results.extend(data.get('results', [])) + url = data.get('next', None) + result['ansible_facts'] = {var: results} + return result + +{%endif%} +{%endfor%} diff --git a/awx/network_ui/templates/action_plugins/update_model.pyt b/awx/network_ui/templates/action_plugins/update_model.pyt new file mode 100644 index 0000000000..f9869173d0 --- /dev/null +++ b/awx/network_ui/templates/action_plugins/update_model.pyt @@ -0,0 +1,44 @@ +{%for model in models-%} +{%-if model.api-%} +#---- update_{{model.name.lower()}} + +from ansible.plugins.action import ActionBase + +import requests +import json + + +class ActionModule(ActionBase): + + BYPASS_HOST_LOOP = True + + def run(self, tmp=None, task_vars=None): + if task_vars is None: + task_vars = dict() + result = super(ActionModule, self).run(tmp, task_vars) + + server = self._task.args.get('server', + "{0}:{1}".format(self._play_context.remote_addr, + self._play_context.port)) + user = self._task.args.get('user', self._play_context.remote_user) + password = self._task.args.get('password', self._play_context.password) + + var = self._task.args.get('var', None) +{%for field in model.fields%} + {{field.name}} = self._task.args.get('{{field.name}}', None){%endfor%} + + url = server + '{{model.v2_end_point}}' + str({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}) + '/' + headers = {'content-type': 'application/json'} + data=dict({%for field in model.fields%}{%if not field.pk%}{{field.name}}={{field.name}}, + {%endif%}{%endfor%}) + data={x:y for x,y in data.iteritems() if y is not None} + response = requests.patch(url, + data=json.dumps(data), + verify=False, + auth=(user, password), + headers=headers) + result['ansible_facts'] = {var: response.json()} + return result + +{%endif%} +{%endfor%} diff --git a/awx/network_ui/templates/library/create_model.pyt b/awx/network_ui/templates/library/create_model.pyt new file mode 100644 index 0000000000..2e660b0edb --- /dev/null +++ b/awx/network_ui/templates/library/create_model.pyt @@ -0,0 +1,5 @@ +{%for model in models-%} +{%-if model.api-%} +#---- create_{{model.name.lower()}} +{%endif%} +{%endfor%} diff --git a/awx/network_ui/templates/library/delete_model.pyt b/awx/network_ui/templates/library/delete_model.pyt new file mode 100644 index 0000000000..161abe65eb --- /dev/null +++ b/awx/network_ui/templates/library/delete_model.pyt @@ -0,0 +1,5 @@ +{%for model in models-%} +{%-if model.api-%} +#---- delete_{{model.name.lower()}} +{%endif%} +{%endfor%} diff --git a/awx/network_ui/templates/library/get_model.pyt b/awx/network_ui/templates/library/get_model.pyt new file mode 100644 index 0000000000..a7c7412e89 --- /dev/null +++ b/awx/network_ui/templates/library/get_model.pyt @@ -0,0 +1,5 @@ +{%for model in models-%} +{%-if model.api-%} +#---- get_{{model.name.lower()}} +{%endif%} +{%endfor%} diff --git a/awx/network_ui/templates/library/list_model.pyt b/awx/network_ui/templates/library/list_model.pyt new file mode 100644 index 0000000000..79e5977b10 --- /dev/null +++ b/awx/network_ui/templates/library/list_model.pyt @@ -0,0 +1,5 @@ +{%for model in models-%} +{%-if model.api-%} +#---- list_{{model.name.lower()}} +{%endif%} +{%endfor%} diff --git a/awx/network_ui/templates/library/update_model.pyt b/awx/network_ui/templates/library/update_model.pyt new file mode 100644 index 0000000000..b7a084d68c --- /dev/null +++ b/awx/network_ui/templates/library/update_model.pyt @@ -0,0 +1,5 @@ +{%for model in models-%} +{%-if model.api-%} +#---- update_{{model.name.lower()}} +{%endif%} +{%endfor%} diff --git a/awx/network_ui/templates/tuples.pyt b/awx/network_ui/templates/tuples.pyt new file mode 100644 index 0000000000..a9917ddc56 --- /dev/null +++ b/awx/network_ui/templates/tuples.pyt @@ -0,0 +1,10 @@ + + +from collections import namedtuple + + +{%for model in models%} +{{model.name}} = namedtuple('{{model.name}}',[{%for field in model.fields%}{%if field.pk%}'{{field.name}}'{%endif%}{%endfor%}, + {%for field in model.fields%}{%if not field.pk%}'{{field.name}}', + {%endif%}{%endfor%}]) +{%endfor%} diff --git a/awx/network_ui/templates/v1_api_client.pyt b/awx/network_ui/templates/v1_api_client.pyt new file mode 100644 index 0000000000..31e099cc8e --- /dev/null +++ b/awx/network_ui/templates/v1_api_client.pyt @@ -0,0 +1,50 @@ + +import requests + +import util +import json +from collections import namedtuple + + +{%for model in models%}{%if model.api%} +{{model.name}} = namedtuple('{{model.name}}',[{%for field in model.fields%}{%if field.pk%}'{{field.name}}'{%endif%}{%endfor%}, + {%for field in model.fields%}{%if not field.pk%}'{{field.name}}', + {%endif%}{%endfor%}]) +{%endif%}{%endfor%} + +{%for model in models%}{%if model.api%} +def list_{{model.name.lower()}}(**kwargs): + response = util.unpaginate(util.get_url(), '{{model.v1_end_point}}', util.get_verify(), util.get_auth(), kwargs) + return response + +def get_{{model.name.lower()}}({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}): + response = requests.get(util.get_url() + "{{model.v1_end_point}}" + str({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + +def create_{{model.name.lower()}}({%for field in model.fields%}{%if not field.pk and field.default is not defined%}{{field.name}},{%endif%}{%endfor%}{%for field in model.fields%}{%if not field.pk and field.default is defined%}{{field.name}}={{field.default}},{%endif%}{%endfor%}): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "{{model.v1_end_point}}", data=json.dumps(dict({%for field in model.fields%}{%if not field.pk%}{{field.name}}={{field.name}}, + {%endif%}{%endfor%})), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + +def update_{{model.name.lower()}}({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}, {%for field in model.fields%}{%if not field.pk%}{{field.name}}=None,{%endif%}{%endfor%}): + headers = {'content-type': 'application/json'} + data=dict({%for field in model.fields%}{%if not field.pk%}{{field.name}}={{field.name}}, + {%endif%}{%endfor%}) + data={x:y for x,y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "{{model.v1_end_point}}" + str({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_{{model.name.lower()}}({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}): + response = requests.delete(util.get_url() + "{{model.v1_end_point}}" + str({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}), verify=util.get_verify(), auth=util.get_auth()) + return response + +{%endif%}{%endfor%} diff --git a/awx/network_ui/templates/v1_api_serializers.pyt b/awx/network_ui/templates/v1_api_serializers.pyt new file mode 100644 index 0000000000..71f8308bad --- /dev/null +++ b/awx/network_ui/templates/v1_api_serializers.pyt @@ -0,0 +1,15 @@ +from awx.api.serializers import BaseSerializer +{%for model in models%}{%if model.api%} +from {{app}}.models import {{model.name}}{%endif%}{%endfor%} + + +{%for model in models%}{%if model.api%} + + + +class {{model.name}}Serializer(BaseSerializer): + class Meta: + model = {{model.name}} + fields = ({%for field in model.fields%}'{{field.name}}'{%if not loop.last%}, + {%endif%}{%endfor%}) +{%endif%}{%endfor%} diff --git a/awx/network_ui/templates/v1_api_urls.pyt b/awx/network_ui/templates/v1_api_urls.pyt new file mode 100644 index 0000000000..3a8a445cbb --- /dev/null +++ b/awx/network_ui/templates/v1_api_urls.pyt @@ -0,0 +1,8 @@ +from rest_framework import routers +from awx.network_ui import v1_api_views + + +router = routers.DefaultRouter() + +{%for model in models%}{%if model.api%} +router.register(r'{{model.name.lower()}}', v1_api_views.{{model.name}}ViewSet){%endif%}{%endfor%} diff --git a/awx/network_ui/templates/v1_api_views.pyt b/awx/network_ui/templates/v1_api_views.pyt new file mode 100644 index 0000000000..e5cee5a0da --- /dev/null +++ b/awx/network_ui/templates/v1_api_views.pyt @@ -0,0 +1,65 @@ +import channels +import json +from rest_framework import viewsets +from utils import transform_dict +{%for model in models%}{%if model.api%} +from {{app}}.models import {{model.name}}{%endif%}{%endfor%} +{%for model in models%}{%if model.api%} +from {{app}}.v1_api_serializers import {{model.name}}Serializer{%endif%}{%endfor%} + +{%for model in models%}{%if model.api%} + + +class {{model.name}}ViewSet(viewsets.ModelViewSet): + + queryset = {{model.name}}.objects.all() + serializer_class = {{model.name}}Serializer + + def create(self, request, *args, **kwargs): + response = super({{model.name}}ViewSet, self).create(request, *args, **kwargs) + print response.data + pk = response.data['{%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}'] + message = dict() + {%if model.create_transform%} + message.update(transform_dict({ {% for key, value in model.create_transform.iteritems()%} '{{key}}':'{{value}}', + {%endfor%} },{{model.name}}.objects.filter(pk=pk).values(*[{% for key in model.create_transform.keys()%}'{{key}}', + {%endfor%}])[0])) + {%else%} + message.update(response.data) + {%endif%} + message['msg_type'] = "{{model.name}}Create" + message['{%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}'] = pk + message['sender'] = 0 + {%if model.topology_id_query %} + print "sending to topologies", {{model.name}}.objects.filter(pk=pk).values_list('{{model.topology_id_query}}', flat=True) + for topology_id in {{model.name}}.objects.filter(pk=pk).values_list('{{model.topology_id_query}}', flat=True): + {%else%} + print "sending to all topologies" + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + {%endif%} + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "{{model.name}}Update" + message['{%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}'] = pk + message['sender'] = 0 + {%if model.topology_id_query %} + for topology_id in {{model.name}}.objects.filter(pk=pk).values_list('{{model.topology_id_query}}', flat=True): + {%else%} + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + {%endif%} + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super({{model.name}}ViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super({{model.name}}ViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super({{model.name}}ViewSet, self).destroy(request, pk, *args, **kwargs) + +{%endif%}{%endfor%} diff --git a/awx/network_ui/templates/v2_api_access.pyt b/awx/network_ui/templates/v2_api_access.pyt new file mode 100644 index 0000000000..bfe47badd7 --- /dev/null +++ b/awx/network_ui/templates/v2_api_access.pyt @@ -0,0 +1,14 @@ +from awx.main.access import BaseAccess, access_registry +{%for model in models%}{%if model.api%} +from {{app}}.models import {{model.name}}{%endif%}{%endfor%} + +{%for model in models%}{%if model.api%} + +class {{model.name}}Access(BaseAccess): + + model = {{model.name}} + +access_registry[{{model.name}}] = {{model.name}}Access +{%endif%}{%endfor%} + + diff --git a/awx/network_ui/templates/v2_api_client.pyt b/awx/network_ui/templates/v2_api_client.pyt new file mode 100644 index 0000000000..eda8e2dc66 --- /dev/null +++ b/awx/network_ui/templates/v2_api_client.pyt @@ -0,0 +1,42 @@ + +import requests + +import util +import json + +{%for model in models%}{%if model.api%} +def list_{{model.name.lower()}}(**kwargs): + response = util.unpaginate(util.get_url(), '{{model.v2_end_point}}', util.get_verify(), util.get_auth(), kwargs) + return response + +def get_{{model.name.lower()}}({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}): + response = requests.get(util.get_url() + "{{model.v2_end_point}}" + str({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}), verify=util.get_verify(), auth=util.get_auth()) + return response.json() + +def create_{{model.name.lower()}}({%for field in model.fields%}{%if not field.pk and field.default is not defined%}{{field.name}},{%endif%}{%endfor%}{%for field in model.fields%}{%if not field.pk and field.default is defined%}{{field.name}}={{field.default}},{%endif%}{%endfor%}): + headers = {'content-type': 'application/json'} + response = requests.post(util.get_url() + "{{model.v2_end_point}}", data=json.dumps(dict({%for field in model.fields%}{%if not field.pk%}{{field.name}}={{field.name}}, + {%endif%}{%endfor%})), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response.json() + +def update_{{model.name.lower()}}({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}, {%for field in model.fields%}{%if not field.pk%}{{field.name}}=None,{%endif%}{%endfor%}): + headers = {'content-type': 'application/json'} + data=dict({%for field in model.fields%}{%if not field.pk%}{{field.name}}={{field.name}}, + {%endif%}{%endfor%}) + data={x:y for x,y in data.iteritems() if y is not None} + response = requests.patch(util.get_url() + "{{model.v2_end_point}}" + str({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}) + "/", + data=json.dumps(data), + verify=util.get_verify(), + auth=util.get_auth(), + headers=headers) + return response + + +def delete_{{model.name.lower()}}({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}): + response = requests.delete(util.get_url() + "{{model.v2_end_point}}" + str({%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}), verify=util.get_verify(), auth=util.get_auth()) + return response + +{%endif%}{%endfor%} diff --git a/awx/network_ui/templates/v2_api_serializers.pyt b/awx/network_ui/templates/v2_api_serializers.pyt new file mode 100644 index 0000000000..71f8308bad --- /dev/null +++ b/awx/network_ui/templates/v2_api_serializers.pyt @@ -0,0 +1,15 @@ +from awx.api.serializers import BaseSerializer +{%for model in models%}{%if model.api%} +from {{app}}.models import {{model.name}}{%endif%}{%endfor%} + + +{%for model in models%}{%if model.api%} + + + +class {{model.name}}Serializer(BaseSerializer): + class Meta: + model = {{model.name}} + fields = ({%for field in model.fields%}'{{field.name}}'{%if not loop.last%}, + {%endif%}{%endfor%}) +{%endif%}{%endfor%} diff --git a/awx/network_ui/templates/v2_api_urls.pyt b/awx/network_ui/templates/v2_api_urls.pyt new file mode 100644 index 0000000000..966d85b918 --- /dev/null +++ b/awx/network_ui/templates/v2_api_urls.pyt @@ -0,0 +1,18 @@ +from django.conf.urls import url +{%for model in models-%}{%if model.api%} +from awx.network_ui.v2_api_views import ({{model.name}}List, {{model.name}}Detail) +{%-endif%} +{%-endfor%} + + +urls = []; +{%for model in models%}{%if model.api%} + +urls += [ + url(r'^{{model.name.lower()}}/$', {{model.name}}List.as_view(), name='canvas_{{model.name.lower()}}_list'), + url(r'^{{model.name.lower()}}/(?P[0-9]+)/$', {{model.name}}Detail.as_view(), name='canvas_{{model.name.lower()}}_detail'), +]; +{%-endif%} +{%-endfor%} + +__all__ = ['urls'] diff --git a/awx/network_ui/templates/v2_api_views.pyt b/awx/network_ui/templates/v2_api_views.pyt new file mode 100644 index 0000000000..e9b93f8636 --- /dev/null +++ b/awx/network_ui/templates/v2_api_views.pyt @@ -0,0 +1,72 @@ +import json +import channels +from utils import transform_dict + +from awx.api.generics import ListCreateAPIView +from awx.api.generics import RetrieveUpdateDestroyAPIView +from {{app}}.models import ({%for model in models%}{%if model.api%}{{model.name}}, + {%endif%}{%endfor%}) +from {{app}}.v2_api_serializers import ({%for model in models%}{%if model.api%}{{model.name}}Serializer, + {%endif%}{%endfor%}) + +{%for model in models%}{%if model.api%} + + +class {{model.name}}List(ListCreateAPIView): + + model = {{model.name}} + serializer_class = {{model.name}}Serializer + + def create(self, request, *args, **kwargs): + response = super({{model.name}}List, self).create(request, *args, **kwargs) + print response.data + pk = response.data['{%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}'] + message = dict() + {%if model.create_transform%} + message.update(transform_dict({ {% for key, value in model.create_transform.iteritems()%} '{{key}}':'{{value}}', + {%endfor%} },{{model.name}}.objects.filter(pk=pk).values(*[{% for key in model.create_transform.keys()%}'{{key}}', + {%endfor%}])[0])) + {%else%} + message.update(response.data) + {%endif%} + message['msg_type'] = "{{model.name}}Create" + message['{%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}'] = pk + message['sender'] = 0 + {%if model.topology_id_query %} + print "sending to topologies", {{model.name}}.objects.filter(pk=pk).values_list('{{model.topology_id_query}}', flat=True) + for topology_id in {{model.name}}.objects.filter(pk=pk).values_list('{{model.topology_id_query}}', flat=True): + {%else%} + print "sending to all topologies" + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + {%endif%} + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + +class {{model.name}}Detail(RetrieveUpdateDestroyAPIView): + + model = {{model.name}} + serializer_class = {{model.name}}Serializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "{{model.name}}Update" + message['{%for field in model.fields%}{%if field.pk%}{{field.name}}{%endif%}{%endfor%}'] = pk + message['sender'] = 0 + {%if model.topology_id_query %} + for topology_id in {{model.name}}.objects.filter(pk=pk).values_list('{{model.topology_id_query}}', flat=True): + {%else%} + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + {%endif%} + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super({{model.name}}Detail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super({{model.name}}Detail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super({{model.name}}Detail, self).destroy(request, pk, *args, **kwargs) + +{%endif%}{%endfor%} diff --git a/awx/network_ui/tuples.py b/awx/network_ui/tuples.py new file mode 100644 index 0000000000..f22801e076 --- /dev/null +++ b/awx/network_ui/tuples.py @@ -0,0 +1,179 @@ + + +from collections import namedtuple + + +Device = namedtuple('Device', ['device_id', + 'topology', + 'name', + 'x', + 'y', + 'id', + 'type', + 'interface_id_seq', + 'process_id_seq', + 'host_id', + ]) + +Link = namedtuple('Link', ['link_id', + 'from_device', + 'to_device', + 'from_interface', + 'to_interface', + 'id', + 'name', + ]) + +Topology = namedtuple('Topology', ['topology_id', + 'name', + 'scale', + 'panX', + 'panY', + 'device_id_seq', + 'link_id_seq', + 'group_id_seq', + 'stream_id_seq', + ]) + +Client = namedtuple('Client', ['client_id', + ]) + +TopologyHistory = namedtuple('TopologyHistory', ['topology_history_id', + 'topology', + 'client', + 'message_type', + 'message_id', + 'message_data', + 'undone', + ]) + +MessageType = namedtuple('MessageType', ['message_type_id', + 'name', + ]) + +Interface = namedtuple('Interface', ['interface_id', + 'device', + 'name', + 'id', + ]) + +Group = namedtuple('Group', ['group_id', + 'id', + 'name', + 'x1', + 'y1', + 'x2', + 'y2', + 'topology', + 'type', + 'inventory_group_id', + ]) + +GroupDevice = namedtuple('GroupDevice', ['group_device_id', + 'group', + 'device', + ]) + +DataBinding = namedtuple('DataBinding', ['data_binding_id', + 'column', + 'row', + 'table', + 'primary_key_id', + 'field', + 'data_type', + 'sheet', + ]) + +DataType = namedtuple('DataType', ['data_type_id', + 'type_name', + ]) + +DataSheet = namedtuple('DataSheet', ['data_sheet_id', + 'name', + 'topology', + 'client', + ]) + +Stream = namedtuple('Stream', ['stream_id', + 'from_device', + 'to_device', + 'label', + 'id', + ]) + +Process = namedtuple('Process', ['process_id', + 'device', + 'name', + 'type', + 'id', + ]) + +Toolbox = namedtuple('Toolbox', ['toolbox_id', + 'name', + ]) + +ToolboxItem = namedtuple('ToolboxItem', ['toolbox_item_id', + 'toolbox', + 'data', + ]) + +FSMTrace = namedtuple('FSMTrace', ['fsm_trace_id', + 'fsm_name', + 'from_state', + 'to_state', + 'message_type', + 'client', + 'trace_session_id', + 'order', + ]) + +TopologyInventory = namedtuple('TopologyInventory', ['topology_inventory_id', + 'topology', + 'inventory_id', + ]) + +EventTrace = namedtuple('EventTrace', ['event_trace_id', + 'client', + 'trace_session_id', + 'event_data', + 'message_id', + ]) + +Coverage = namedtuple('Coverage', ['coverage_id', + 'coverage_data', + 'test_result', + ]) + +TopologySnapshot = namedtuple('TopologySnapshot', ['topology_snapshot_id', + 'client', + 'topology_id', + 'trace_session_id', + 'snapshot_data', + 'order', + ]) + +TestCase = namedtuple('TestCase', ['test_case_id', + 'name', + 'test_case_data', + ]) + +Result = namedtuple('Result', ['result_id', + 'name', + ]) + +CodeUnderTest = namedtuple('CodeUnderTest', ['code_under_test_id', + 'version_x', + 'version_y', + 'version_z', + 'commits_since', + 'commit_hash', + ]) + +TestResult = namedtuple('TestResult', ['test_result_id', + 'test_case', + 'result', + 'code_under_test', + 'time', + 'id', + 'client', + ]) diff --git a/awx/network_ui/urls.py b/awx/network_ui/urls.py index f16ca6590e..7aad106bc0 100644 --- a/awx/network_ui/urls.py +++ b/awx/network_ui/urls.py @@ -1,9 +1,13 @@ # Copyright (c) 2017 Red Hat, Inc -from django.conf.urls import include, url -import sys +from django.conf.urls import url, include -from . import views -import awx.network_ui.routing +import awx.api.urls + +from awx.network_ui import views +from awx.network_ui import v1_api_urls +from awx.network_ui import v2_api_urls + +import awx.network_ui.v2_api_access app_name = 'network_ui' urlpatterns = [ @@ -14,6 +18,13 @@ urlpatterns = [ url(r'^download_recording$', views.download_recording, name='download_recording'), url(r'^topology.json$', views.json_topology_data, name='json_topology_data'), url(r'^topology.yaml$', views.yaml_topology_data, name='json_topology_data'), - url(r'^$', views.index, name='index'), + url(r'^api/v1/', include(v1_api_urls.router.urls)), +] + +urlpatterns += [ + url(r'^api/(?P(v2))/canvas/', include(v2_api_urls.urls)) +] +awx.api.urls.urlpatterns += [ + url(r'^(?P(v2))/canvas/', include(v2_api_urls.urls)) ] diff --git a/awx/network_ui/v1_api_serializers.py b/awx/network_ui/v1_api_serializers.py new file mode 100644 index 0000000000..549b8eaf87 --- /dev/null +++ b/awx/network_ui/v1_api_serializers.py @@ -0,0 +1,128 @@ +from awx.api.serializers import BaseSerializer + +from awx.network_ui.models import Device +from awx.network_ui.models import Link +from awx.network_ui.models import Topology +from awx.network_ui.models import Interface +from awx.network_ui.models import Group +from awx.network_ui.models import GroupDevice +from awx.network_ui.models import Stream +from awx.network_ui.models import Process +from awx.network_ui.models import Toolbox +from awx.network_ui.models import ToolboxItem +from awx.network_ui.models import TopologyInventory + + +class DeviceSerializer(BaseSerializer): + class Meta: + model = Device + fields = ('device_id', + 'topology', + 'name', + 'x', + 'y', + 'id', + 'type', + 'interface_id_seq', + 'process_id_seq', + 'host_id') + + +class LinkSerializer(BaseSerializer): + class Meta: + model = Link + fields = ('link_id', + 'from_device', + 'to_device', + 'from_interface', + 'to_interface', + 'id', + 'name') + + +class TopologySerializer(BaseSerializer): + class Meta: + model = Topology + fields = ('topology_id', + 'name', + 'scale', + 'panX', + 'panY', + 'device_id_seq', + 'link_id_seq', + 'group_id_seq', + 'stream_id_seq') + + +class InterfaceSerializer(BaseSerializer): + class Meta: + model = Interface + fields = ('interface_id', + 'device', + 'name', + 'id') + + +class GroupSerializer(BaseSerializer): + class Meta: + model = Group + fields = ('group_id', + 'id', + 'name', + 'x1', + 'y1', + 'x2', + 'y2', + 'topology', + 'type') + + +class GroupDeviceSerializer(BaseSerializer): + class Meta: + model = GroupDevice + fields = ('group_device_id', + 'group', + 'device') + + +class StreamSerializer(BaseSerializer): + class Meta: + model = Stream + fields = ('stream_id', + 'from_device', + 'to_device', + 'label', + 'id') + + +class ProcessSerializer(BaseSerializer): + class Meta: + model = Process + fields = ('process_id', + 'device', + 'name', + 'type', + 'id') + + +class ToolboxSerializer(BaseSerializer): + class Meta: + model = Toolbox + fields = ('toolbox_id', + 'name') + + +class ToolboxItemSerializer(BaseSerializer): + class Meta: + model = ToolboxItem + fields = ('toolbox_item_id', + 'toolbox', + 'data') + + +class TopologyInventorySerializer(BaseSerializer): + class Meta: + model = TopologyInventory + fields = ('topology_inventory_id', + 'topology', + 'inventory_id') diff --git a/awx/network_ui/v1_api_urls.py b/awx/network_ui/v1_api_urls.py new file mode 100644 index 0000000000..32a10a77de --- /dev/null +++ b/awx/network_ui/v1_api_urls.py @@ -0,0 +1,18 @@ +from rest_framework import routers +from awx.network_ui import v1_api_views + + +router = routers.DefaultRouter() + + +router.register(r'device', v1_api_views.DeviceViewSet) +router.register(r'link', v1_api_views.LinkViewSet) +router.register(r'topology', v1_api_views.TopologyViewSet) +router.register(r'interface', v1_api_views.InterfaceViewSet) +router.register(r'group', v1_api_views.GroupViewSet) +router.register(r'groupdevice', v1_api_views.GroupDeviceViewSet) +router.register(r'stream', v1_api_views.StreamViewSet) +router.register(r'process', v1_api_views.ProcessViewSet) +router.register(r'toolbox', v1_api_views.ToolboxViewSet) +router.register(r'toolboxitem', v1_api_views.ToolboxItemViewSet) +router.register(r'topologyinventory', v1_api_views.TopologyInventoryViewSet) diff --git a/awx/network_ui/v1_api_views.py b/awx/network_ui/v1_api_views.py new file mode 100644 index 0000000000..e05313a7a5 --- /dev/null +++ b/awx/network_ui/v1_api_views.py @@ -0,0 +1,556 @@ +import channels +import json +from rest_framework import viewsets +from utils import transform_dict + +from awx.network_ui.models import Device +from awx.network_ui.models import Link +from awx.network_ui.models import Topology +from awx.network_ui.models import Interface +from awx.network_ui.models import Group +from awx.network_ui.models import GroupDevice +from awx.network_ui.models import Stream +from awx.network_ui.models import Process +from awx.network_ui.models import Toolbox +from awx.network_ui.models import ToolboxItem +from awx.network_ui.models import TopologyInventory + +from awx.network_ui.v1_api_serializers import DeviceSerializer +from awx.network_ui.v1_api_serializers import LinkSerializer +from awx.network_ui.v1_api_serializers import TopologySerializer +from awx.network_ui.v1_api_serializers import InterfaceSerializer +from awx.network_ui.v1_api_serializers import GroupSerializer +from awx.network_ui.v1_api_serializers import GroupDeviceSerializer +from awx.network_ui.v1_api_serializers import StreamSerializer +from awx.network_ui.v1_api_serializers import ProcessSerializer +from awx.network_ui.v1_api_serializers import ToolboxSerializer +from awx.network_ui.v1_api_serializers import ToolboxItemSerializer +from awx.network_ui.v1_api_serializers import TopologyInventorySerializer + + +class DeviceViewSet(viewsets.ModelViewSet): + + queryset = Device.objects.all() + serializer_class = DeviceSerializer + + def create(self, request, *args, **kwargs): + response = super(DeviceViewSet, self).create(request, *args, **kwargs) + print response.data + pk = response.data['device_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "DeviceCreate" + message['device_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Device.objects.filter(pk=pk).values_list('topology_id', flat=True) + for topology_id in Device.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "DeviceUpdate" + message['device_id'] = pk + message['sender'] = 0 + + for topology_id in Device.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(DeviceViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(DeviceViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(DeviceViewSet, self).destroy(request, pk, *args, **kwargs) + + +class LinkViewSet(viewsets.ModelViewSet): + + queryset = Link.objects.all() + serializer_class = LinkSerializer + + def create(self, request, *args, **kwargs): + response = super(LinkViewSet, self).create(request, *args, **kwargs) + print response.data + pk = response.data['link_id'] + message = dict() + + message.update(transform_dict({'to_device__id': 'to_device_id', + 'from_interface__id': 'from_interface_id', + 'name': 'name', + 'from_device__id': 'from_device_id', + 'id': 'id', + 'to_interface__id': 'to_interface_id', + }, Link.objects.filter(pk=pk).values(*['to_device__id', + 'from_interface__id', + 'name', + 'from_device__id', + 'id', + 'to_interface__id', + ])[0])) + + message['msg_type'] = "LinkCreate" + message['link_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Link.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True) + for topology_id in Link.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "LinkUpdate" + message['link_id'] = pk + message['sender'] = 0 + + for topology_id in Link.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(LinkViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(LinkViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(LinkViewSet, self).destroy(request, pk, *args, **kwargs) + + +class TopologyViewSet(viewsets.ModelViewSet): + + queryset = Topology.objects.all() + serializer_class = TopologySerializer + + def create(self, request, *args, **kwargs): + response = super(TopologyViewSet, self).create(request, *args, **kwargs) + print response.data + pk = response.data['topology_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "TopologyCreate" + message['topology_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Topology.objects.filter(pk=pk).values_list('topology_id', flat=True) + for topology_id in Topology.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "TopologyUpdate" + message['topology_id'] = pk + message['sender'] = 0 + + for topology_id in Topology.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(TopologyViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(TopologyViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(TopologyViewSet, self).destroy(request, pk, *args, **kwargs) + + +class InterfaceViewSet(viewsets.ModelViewSet): + + queryset = Interface.objects.all() + serializer_class = InterfaceSerializer + + def create(self, request, *args, **kwargs): + response = super(InterfaceViewSet, self).create( + request, *args, **kwargs) + print response.data + pk = response.data['interface_id'] + message = dict() + + message.update(transform_dict({'id': 'id', + 'device__id': 'device_id', + 'name': 'name', + }, Interface.objects.filter(pk=pk).values(*['id', + 'device__id', + 'name', + ])[0])) + + message['msg_type'] = "InterfaceCreate" + message['interface_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Interface.objects.filter(pk=pk).values_list('device__topology_id', flat=True) + for topology_id in Interface.objects.filter(pk=pk).values_list('device__topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "InterfaceUpdate" + message['interface_id'] = pk + message['sender'] = 0 + + for topology_id in Interface.objects.filter(pk=pk).values_list('device__topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(InterfaceViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(InterfaceViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(InterfaceViewSet, self).destroy(request, pk, *args, **kwargs) + + +class GroupViewSet(viewsets.ModelViewSet): + + queryset = Group.objects.all() + serializer_class = GroupSerializer + + def create(self, request, *args, **kwargs): + response = super(GroupViewSet, self).create(request, *args, **kwargs) + print response.data + pk = response.data['group_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "GroupCreate" + message['group_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Group.objects.filter(pk=pk).values_list('topology_id', flat=True) + for topology_id in Group.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "GroupUpdate" + message['group_id'] = pk + message['sender'] = 0 + + for topology_id in Group.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(GroupViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(GroupViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(GroupViewSet, self).destroy(request, pk, *args, **kwargs) + + +class GroupDeviceViewSet(viewsets.ModelViewSet): + + queryset = GroupDevice.objects.all() + serializer_class = GroupDeviceSerializer + + def create(self, request, *args, **kwargs): + response = super(GroupDeviceViewSet, self).create( + request, *args, **kwargs) + print response.data + pk = response.data['group_device_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "GroupDeviceCreate" + message['group_device_id'] = pk + message['sender'] = 0 + + print "sending to topologies", GroupDevice.objects.filter(pk=pk).values_list('group__topology_id', flat=True) + for topology_id in GroupDevice.objects.filter(pk=pk).values_list('group__topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "GroupDeviceUpdate" + message['group_device_id'] = pk + message['sender'] = 0 + + for topology_id in GroupDevice.objects.filter(pk=pk).values_list('group__topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(GroupDeviceViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(GroupDeviceViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(GroupDeviceViewSet, self).destroy(request, pk, *args, **kwargs) + + +class StreamViewSet(viewsets.ModelViewSet): + + queryset = Stream.objects.all() + serializer_class = StreamSerializer + + def create(self, request, *args, **kwargs): + response = super(StreamViewSet, self).create(request, *args, **kwargs) + print response.data + pk = response.data['stream_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "StreamCreate" + message['stream_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Stream.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True) + for topology_id in Stream.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "StreamUpdate" + message['stream_id'] = pk + message['sender'] = 0 + + for topology_id in Stream.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(StreamViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(StreamViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(StreamViewSet, self).destroy(request, pk, *args, **kwargs) + + +class ProcessViewSet(viewsets.ModelViewSet): + + queryset = Process.objects.all() + serializer_class = ProcessSerializer + + def create(self, request, *args, **kwargs): + response = super(ProcessViewSet, self).create(request, *args, **kwargs) + print response.data + pk = response.data['process_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "ProcessCreate" + message['process_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Process.objects.filter(pk=pk).values_list('device__topology_id', flat=True) + for topology_id in Process.objects.filter(pk=pk).values_list('device__topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "ProcessUpdate" + message['process_id'] = pk + message['sender'] = 0 + + for topology_id in Process.objects.filter(pk=pk).values_list('device__topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(ProcessViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(ProcessViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(ProcessViewSet, self).destroy(request, pk, *args, **kwargs) + + +class ToolboxViewSet(viewsets.ModelViewSet): + + queryset = Toolbox.objects.all() + serializer_class = ToolboxSerializer + + def create(self, request, *args, **kwargs): + response = super(ToolboxViewSet, self).create(request, *args, **kwargs) + print response.data + pk = response.data['toolbox_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "ToolboxCreate" + message['toolbox_id'] = pk + message['sender'] = 0 + + print "sending to all topologies" + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "ToolboxUpdate" + message['toolbox_id'] = pk + message['sender'] = 0 + + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(ToolboxViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(ToolboxViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(ToolboxViewSet, self).destroy(request, pk, *args, **kwargs) + + +class ToolboxItemViewSet(viewsets.ModelViewSet): + + queryset = ToolboxItem.objects.all() + serializer_class = ToolboxItemSerializer + + def create(self, request, *args, **kwargs): + response = super(ToolboxItemViewSet, self).create( + request, *args, **kwargs) + print response.data + pk = response.data['toolbox_item_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "ToolboxItemCreate" + message['toolbox_item_id'] = pk + message['sender'] = 0 + + print "sending to all topologies" + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "ToolboxItemUpdate" + message['toolbox_item_id'] = pk + message['sender'] = 0 + + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(ToolboxItemViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(ToolboxItemViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(ToolboxItemViewSet, self).destroy(request, pk, *args, **kwargs) + + +class TopologyInventoryViewSet(viewsets.ModelViewSet): + + queryset = TopologyInventory.objects.all() + serializer_class = TopologyInventorySerializer + + def create(self, request, *args, **kwargs): + response = super(TopologyInventoryViewSet, self).create( + request, *args, **kwargs) + print response.data + pk = response.data['topology_inventory_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "TopologyInventoryCreate" + message['topology_inventory_id'] = pk + message['sender'] = 0 + + print "sending to topologies", TopologyInventory.objects.filter(pk=pk).values_list('topology_id', flat=True) + for topology_id in TopologyInventory.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "TopologyInventoryUpdate" + message['topology_inventory_id'] = pk + message['sender'] = 0 + + for topology_id in TopologyInventory.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group( + "topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(TopologyInventoryViewSet, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(TopologyInventoryViewSet, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(TopologyInventoryViewSet, self).destroy(request, pk, *args, **kwargs) diff --git a/awx/network_ui/v2_api_access.py b/awx/network_ui/v2_api_access.py new file mode 100644 index 0000000000..398e467032 --- /dev/null +++ b/awx/network_ui/v2_api_access.py @@ -0,0 +1,101 @@ +from awx.main.access import BaseAccess, access_registry + +from awx.network_ui.models import Device +from awx.network_ui.models import Link +from awx.network_ui.models import Topology +from awx.network_ui.models import Interface +from awx.network_ui.models import Group +from awx.network_ui.models import GroupDevice +from awx.network_ui.models import Stream +from awx.network_ui.models import Process +from awx.network_ui.models import Toolbox +from awx.network_ui.models import ToolboxItem +from awx.network_ui.models import TopologyInventory + + +class DeviceAccess(BaseAccess): + + model = Device + + +access_registry[Device] = DeviceAccess + + +class LinkAccess(BaseAccess): + + model = Link + + +access_registry[Link] = LinkAccess + + +class TopologyAccess(BaseAccess): + + model = Topology + + +access_registry[Topology] = TopologyAccess + + +class InterfaceAccess(BaseAccess): + + model = Interface + + +access_registry[Interface] = InterfaceAccess + + +class GroupAccess(BaseAccess): + + model = Group + + +access_registry[Group] = GroupAccess + + +class GroupDeviceAccess(BaseAccess): + + model = GroupDevice + + +access_registry[GroupDevice] = GroupDeviceAccess + + +class StreamAccess(BaseAccess): + + model = Stream + + +access_registry[Stream] = StreamAccess + + +class ProcessAccess(BaseAccess): + + model = Process + + +access_registry[Process] = ProcessAccess + + +class ToolboxAccess(BaseAccess): + + model = Toolbox + + +access_registry[Toolbox] = ToolboxAccess + + +class ToolboxItemAccess(BaseAccess): + + model = ToolboxItem + + +access_registry[ToolboxItem] = ToolboxItemAccess + + +class TopologyInventoryAccess(BaseAccess): + + model = TopologyInventory + + +access_registry[TopologyInventory] = TopologyInventoryAccess diff --git a/awx/network_ui/v2_api_serializers.py b/awx/network_ui/v2_api_serializers.py new file mode 100644 index 0000000000..549b8eaf87 --- /dev/null +++ b/awx/network_ui/v2_api_serializers.py @@ -0,0 +1,128 @@ +from awx.api.serializers import BaseSerializer + +from awx.network_ui.models import Device +from awx.network_ui.models import Link +from awx.network_ui.models import Topology +from awx.network_ui.models import Interface +from awx.network_ui.models import Group +from awx.network_ui.models import GroupDevice +from awx.network_ui.models import Stream +from awx.network_ui.models import Process +from awx.network_ui.models import Toolbox +from awx.network_ui.models import ToolboxItem +from awx.network_ui.models import TopologyInventory + + +class DeviceSerializer(BaseSerializer): + class Meta: + model = Device + fields = ('device_id', + 'topology', + 'name', + 'x', + 'y', + 'id', + 'type', + 'interface_id_seq', + 'process_id_seq', + 'host_id') + + +class LinkSerializer(BaseSerializer): + class Meta: + model = Link + fields = ('link_id', + 'from_device', + 'to_device', + 'from_interface', + 'to_interface', + 'id', + 'name') + + +class TopologySerializer(BaseSerializer): + class Meta: + model = Topology + fields = ('topology_id', + 'name', + 'scale', + 'panX', + 'panY', + 'device_id_seq', + 'link_id_seq', + 'group_id_seq', + 'stream_id_seq') + + +class InterfaceSerializer(BaseSerializer): + class Meta: + model = Interface + fields = ('interface_id', + 'device', + 'name', + 'id') + + +class GroupSerializer(BaseSerializer): + class Meta: + model = Group + fields = ('group_id', + 'id', + 'name', + 'x1', + 'y1', + 'x2', + 'y2', + 'topology', + 'type') + + +class GroupDeviceSerializer(BaseSerializer): + class Meta: + model = GroupDevice + fields = ('group_device_id', + 'group', + 'device') + + +class StreamSerializer(BaseSerializer): + class Meta: + model = Stream + fields = ('stream_id', + 'from_device', + 'to_device', + 'label', + 'id') + + +class ProcessSerializer(BaseSerializer): + class Meta: + model = Process + fields = ('process_id', + 'device', + 'name', + 'type', + 'id') + + +class ToolboxSerializer(BaseSerializer): + class Meta: + model = Toolbox + fields = ('toolbox_id', + 'name') + + +class ToolboxItemSerializer(BaseSerializer): + class Meta: + model = ToolboxItem + fields = ('toolbox_item_id', + 'toolbox', + 'data') + + +class TopologyInventorySerializer(BaseSerializer): + class Meta: + model = TopologyInventory + fields = ('topology_inventory_id', + 'topology', + 'inventory_id') diff --git a/awx/network_ui/v2_api_urls.py b/awx/network_ui/v2_api_urls.py new file mode 100644 index 0000000000..e98bc10eae --- /dev/null +++ b/awx/network_ui/v2_api_urls.py @@ -0,0 +1,74 @@ +from django.conf.urls import url + +from awx.network_ui.v2_api_views import (DeviceList, DeviceDetail) +from awx.network_ui.v2_api_views import (LinkList, LinkDetail) +from awx.network_ui.v2_api_views import (TopologyList, TopologyDetail) +from awx.network_ui.v2_api_views import (InterfaceList, InterfaceDetail) +from awx.network_ui.v2_api_views import (GroupList, GroupDetail) +from awx.network_ui.v2_api_views import (GroupDeviceList, GroupDeviceDetail) +from awx.network_ui.v2_api_views import (StreamList, StreamDetail) +from awx.network_ui.v2_api_views import (ProcessList, ProcessDetail) +from awx.network_ui.v2_api_views import (ToolboxList, ToolboxDetail) +from awx.network_ui.v2_api_views import (ToolboxItemList, ToolboxItemDetail) +from awx.network_ui.v2_api_views import (TopologyInventoryList, TopologyInventoryDetail) + + +urls = [] + + +urls += [ + url(r'^device/$', DeviceList.as_view(), name='canvas_device_list'), + url(r'^device/(?P[0-9]+)/$', DeviceDetail.as_view(), name='canvas_device_detail'), +] + +urls += [ + url(r'^link/$', LinkList.as_view(), name='canvas_link_list'), + url(r'^link/(?P[0-9]+)/$', LinkDetail.as_view(), name='canvas_link_detail'), +] + +urls += [ + url(r'^topology/$', TopologyList.as_view(), name='canvas_topology_list'), + url(r'^topology/(?P[0-9]+)/$', TopologyDetail.as_view(), name='canvas_topology_detail'), +] + +urls += [ + url(r'^interface/$', InterfaceList.as_view(), name='canvas_interface_list'), + url(r'^interface/(?P[0-9]+)/$', InterfaceDetail.as_view(), name='canvas_interface_detail'), +] + +urls += [ + url(r'^group/$', GroupList.as_view(), name='canvas_group_list'), + url(r'^group/(?P[0-9]+)/$', GroupDetail.as_view(), name='canvas_group_detail'), +] + +urls += [ + url(r'^groupdevice/$', GroupDeviceList.as_view(), name='canvas_groupdevice_list'), + url(r'^groupdevice/(?P[0-9]+)/$', GroupDeviceDetail.as_view(), name='canvas_groupdevice_detail'), +] + +urls += [ + url(r'^stream/$', StreamList.as_view(), name='canvas_stream_list'), + url(r'^stream/(?P[0-9]+)/$', StreamDetail.as_view(), name='canvas_stream_detail'), +] + +urls += [ + url(r'^process/$', ProcessList.as_view(), name='canvas_process_list'), + url(r'^process/(?P[0-9]+)/$', ProcessDetail.as_view(), name='canvas_process_detail'), +] + +urls += [ + url(r'^toolbox/$', ToolboxList.as_view(), name='canvas_toolbox_list'), + url(r'^toolbox/(?P[0-9]+)/$', ToolboxDetail.as_view(), name='canvas_toolbox_detail'), +] + +urls += [ + url(r'^toolboxitem/$', ToolboxItemList.as_view(), name='canvas_toolboxitem_list'), + url(r'^toolboxitem/(?P[0-9]+)/$', ToolboxItemDetail.as_view(), name='canvas_toolboxitem_detail'), +] + +urls += [ + url(r'^topologyinventory/$', TopologyInventoryList.as_view(), name='canvas_topologyinventory_list'), + url(r'^topologyinventory/(?P[0-9]+)/$', TopologyInventoryDetail.as_view(), name='canvas_topologyinventory_detail'), +] + +__all__ = ['urls'] diff --git a/awx/network_ui/v2_api_views.py b/awx/network_ui/v2_api_views.py new file mode 100644 index 0000000000..96922e3484 --- /dev/null +++ b/awx/network_ui/v2_api_views.py @@ -0,0 +1,598 @@ +import json +import channels +from utils import transform_dict + +from awx.api.generics import ListCreateAPIView +from awx.api.generics import RetrieveUpdateDestroyAPIView +from awx.network_ui.models import (Device, + Link, + Topology, + Interface, + Group, + GroupDevice, + Stream, + Process, + Toolbox, + ToolboxItem, + TopologyInventory, + ) +from awx.network_ui.v2_api_serializers import (DeviceSerializer, + LinkSerializer, + TopologySerializer, + InterfaceSerializer, + GroupSerializer, + GroupDeviceSerializer, + StreamSerializer, + ProcessSerializer, + ToolboxSerializer, + ToolboxItemSerializer, + TopologyInventorySerializer, + ) + + +class DeviceList(ListCreateAPIView): + + model = Device + serializer_class = DeviceSerializer + + def create(self, request, *args, **kwargs): + response = super(DeviceList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['device_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "DeviceCreate" + message['device_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Device.objects.filter(pk=pk).values_list('topology_id', flat=True) + for topology_id in Device.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class DeviceDetail(RetrieveUpdateDestroyAPIView): + + model = Device + serializer_class = DeviceSerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "DeviceUpdate" + message['device_id'] = pk + message['sender'] = 0 + + for topology_id in Device.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(DeviceDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(DeviceDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(DeviceDetail, self).destroy(request, pk, *args, **kwargs) + + +class LinkList(ListCreateAPIView): + + model = Link + serializer_class = LinkSerializer + + def create(self, request, *args, **kwargs): + response = super(LinkList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['link_id'] + message = dict() + + message.update(transform_dict({'to_device__id': 'to_device_id', + 'from_interface__id': 'from_interface_id', + 'name': 'name', + 'from_device__id': 'from_device_id', + 'id': 'id', + 'to_interface__id': 'to_interface_id', + }, Link.objects.filter(pk=pk).values(*['to_device__id', + 'from_interface__id', + 'name', + 'from_device__id', + 'id', + 'to_interface__id', + ])[0])) + + message['msg_type'] = "LinkCreate" + message['link_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Link.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True) + for topology_id in Link.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class LinkDetail(RetrieveUpdateDestroyAPIView): + + model = Link + serializer_class = LinkSerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "LinkUpdate" + message['link_id'] = pk + message['sender'] = 0 + + for topology_id in Link.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(LinkDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(LinkDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(LinkDetail, self).destroy(request, pk, *args, **kwargs) + + +class TopologyList(ListCreateAPIView): + + model = Topology + serializer_class = TopologySerializer + + def create(self, request, *args, **kwargs): + response = super(TopologyList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['topology_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "TopologyCreate" + message['topology_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Topology.objects.filter(pk=pk).values_list('topology_id', flat=True) + for topology_id in Topology.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class TopologyDetail(RetrieveUpdateDestroyAPIView): + + model = Topology + serializer_class = TopologySerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "TopologyUpdate" + message['topology_id'] = pk + message['sender'] = 0 + + for topology_id in Topology.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(TopologyDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(TopologyDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(TopologyDetail, self).destroy(request, pk, *args, **kwargs) + + +class InterfaceList(ListCreateAPIView): + + model = Interface + serializer_class = InterfaceSerializer + + def create(self, request, *args, **kwargs): + response = super(InterfaceList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['interface_id'] + message = dict() + + message.update(transform_dict({'id': 'id', + 'device__id': 'device_id', + 'name': 'name', + }, Interface.objects.filter(pk=pk).values(*['id', + 'device__id', + 'name', + ])[0])) + + message['msg_type'] = "InterfaceCreate" + message['interface_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Interface.objects.filter(pk=pk).values_list('device__topology_id', flat=True) + for topology_id in Interface.objects.filter(pk=pk).values_list('device__topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class InterfaceDetail(RetrieveUpdateDestroyAPIView): + + model = Interface + serializer_class = InterfaceSerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "InterfaceUpdate" + message['interface_id'] = pk + message['sender'] = 0 + + for topology_id in Interface.objects.filter(pk=pk).values_list('device__topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(InterfaceDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(InterfaceDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(InterfaceDetail, self).destroy(request, pk, *args, **kwargs) + + +class GroupList(ListCreateAPIView): + + model = Group + serializer_class = GroupSerializer + + def create(self, request, *args, **kwargs): + response = super(GroupList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['group_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "GroupCreate" + message['group_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Group.objects.filter(pk=pk).values_list('topology_id', flat=True) + for topology_id in Group.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class GroupDetail(RetrieveUpdateDestroyAPIView): + + model = Group + serializer_class = GroupSerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "GroupUpdate" + message['group_id'] = pk + message['sender'] = 0 + + for topology_id in Group.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(GroupDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(GroupDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(GroupDetail, self).destroy(request, pk, *args, **kwargs) + + +class GroupDeviceList(ListCreateAPIView): + + model = GroupDevice + serializer_class = GroupDeviceSerializer + + def create(self, request, *args, **kwargs): + response = super(GroupDeviceList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['group_device_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "GroupDeviceCreate" + message['group_device_id'] = pk + message['sender'] = 0 + + print "sending to topologies", GroupDevice.objects.filter(pk=pk).values_list('group__topology_id', flat=True) + for topology_id in GroupDevice.objects.filter(pk=pk).values_list('group__topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class GroupDeviceDetail(RetrieveUpdateDestroyAPIView): + + model = GroupDevice + serializer_class = GroupDeviceSerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "GroupDeviceUpdate" + message['group_device_id'] = pk + message['sender'] = 0 + + for topology_id in GroupDevice.objects.filter(pk=pk).values_list('group__topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(GroupDeviceDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(GroupDeviceDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(GroupDeviceDetail, self).destroy(request, pk, *args, **kwargs) + + +class StreamList(ListCreateAPIView): + + model = Stream + serializer_class = StreamSerializer + + def create(self, request, *args, **kwargs): + response = super(StreamList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['stream_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "StreamCreate" + message['stream_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Stream.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True) + for topology_id in Stream.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class StreamDetail(RetrieveUpdateDestroyAPIView): + + model = Stream + serializer_class = StreamSerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "StreamUpdate" + message['stream_id'] = pk + message['sender'] = 0 + + for topology_id in Stream.objects.filter(pk=pk).values_list('from_device__topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(StreamDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(StreamDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(StreamDetail, self).destroy(request, pk, *args, **kwargs) + + +class ProcessList(ListCreateAPIView): + + model = Process + serializer_class = ProcessSerializer + + def create(self, request, *args, **kwargs): + response = super(ProcessList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['process_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "ProcessCreate" + message['process_id'] = pk + message['sender'] = 0 + + print "sending to topologies", Process.objects.filter(pk=pk).values_list('device__topology_id', flat=True) + for topology_id in Process.objects.filter(pk=pk).values_list('device__topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class ProcessDetail(RetrieveUpdateDestroyAPIView): + + model = Process + serializer_class = ProcessSerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "ProcessUpdate" + message['process_id'] = pk + message['sender'] = 0 + + for topology_id in Process.objects.filter(pk=pk).values_list('device__topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(ProcessDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(ProcessDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(ProcessDetail, self).destroy(request, pk, *args, **kwargs) + + +class ToolboxList(ListCreateAPIView): + + model = Toolbox + serializer_class = ToolboxSerializer + + def create(self, request, *args, **kwargs): + response = super(ToolboxList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['toolbox_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "ToolboxCreate" + message['toolbox_id'] = pk + message['sender'] = 0 + + print "sending to all topologies" + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class ToolboxDetail(RetrieveUpdateDestroyAPIView): + + model = Toolbox + serializer_class = ToolboxSerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "ToolboxUpdate" + message['toolbox_id'] = pk + message['sender'] = 0 + + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(ToolboxDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(ToolboxDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(ToolboxDetail, self).destroy(request, pk, *args, **kwargs) + + +class ToolboxItemList(ListCreateAPIView): + + model = ToolboxItem + serializer_class = ToolboxItemSerializer + + def create(self, request, *args, **kwargs): + response = super(ToolboxItemList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['toolbox_item_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "ToolboxItemCreate" + message['toolbox_item_id'] = pk + message['sender'] = 0 + + print "sending to all topologies" + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class ToolboxItemDetail(RetrieveUpdateDestroyAPIView): + + model = ToolboxItem + serializer_class = ToolboxItemSerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "ToolboxItemUpdate" + message['toolbox_item_id'] = pk + message['sender'] = 0 + + for topology_id in Topology.objects.all().values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(ToolboxItemDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(ToolboxItemDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(ToolboxItemDetail, self).destroy(request, pk, *args, **kwargs) + + +class TopologyInventoryList(ListCreateAPIView): + + model = TopologyInventory + serializer_class = TopologyInventorySerializer + + def create(self, request, *args, **kwargs): + response = super(TopologyInventoryList, self).create(request, *args, **kwargs) + print response.data + pk = response.data['topology_inventory_id'] + message = dict() + + message.update(response.data) + + message['msg_type'] = "TopologyInventoryCreate" + message['topology_inventory_id'] = pk + message['sender'] = 0 + + print "sending to topologies", TopologyInventory.objects.filter(pk=pk).values_list('topology_id', flat=True) + for topology_id in TopologyInventory.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + print "Sent message", message + return response + + +class TopologyInventoryDetail(RetrieveUpdateDestroyAPIView): + + model = TopologyInventory + serializer_class = TopologyInventorySerializer + + def update(self, request, pk=None, *args, **kwargs): + message = dict() + message.update(json.loads(request.body)) + message['msg_type'] = "TopologyInventoryUpdate" + message['topology_inventory_id'] = pk + message['sender'] = 0 + + for topology_id in TopologyInventory.objects.filter(pk=pk).values_list('topology_id', flat=True): + + channels.Group("topology-%s" % topology_id).send({"text": json.dumps([message['msg_type'], message])}) + + return super(TopologyInventoryDetail, self).update(request, pk, *args, **kwargs) + + def partial_update(self, request, pk=None, *args, **kwargs): + return super(TopologyInventoryDetail, self).partial_update(request, pk, *args, **kwargs) + + def destroy(self, request, pk=None, *args, **kwargs): + return super(TopologyInventoryDetail, self).destroy(request, pk, *args, **kwargs)