Commit d5c96378 by Szabolcs Gelencser

Add initial network topology view (editor)

parent 09b07ed6
......@@ -2,10 +2,29 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="1fbec8af-5a7c-40f9-b994-83ac07d1ae1d" name="Default" comment="">
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_alert_message.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_confirm.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_loading_inline.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_loading_modal.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_membership.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_modal.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_progress.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_script_loader.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_table_row.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/template.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/templates.html" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templatetags/__init__.py" />
<change beforePath="" afterPath="$PROJECT_DIR$/circle/network/templatetags/horizon.py" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" />
<change beforePath="$PROJECT_DIR$/circle/circle/settings/local.py" afterPath="$PROJECT_DIR$/circle/circle/settings/local.py" />
<change beforePath="$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail/console.html" afterPath="$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail/console.html" />
<change beforePath="$PROJECT_DIR$/circle/dashboard/views/vm.py" afterPath="$PROJECT_DIR$/circle/dashboard/views/vm.py" />
<change beforePath="$PROJECT_DIR$/circle/bower.json" afterPath="$PROJECT_DIR$/circle/bower.json" />
<change beforePath="$PROJECT_DIR$/circle/circle/settings/base.py" afterPath="$PROJECT_DIR$/circle/circle/settings/base.py" />
<change beforePath="$PROJECT_DIR$/circle/dashboard/static/dashboard/js/horizon.flatnetworktopology.js" afterPath="" />
<change beforePath="$PROJECT_DIR$/circle/dashboard/static/dashboard/js/horizon.networktopology.js" afterPath="" />
<change beforePath="$PROJECT_DIR$/circle/dashboard/static/dashboard/js/horizon.networktopologycommon.js" afterPath="" />
<change beforePath="$PROJECT_DIR$/circle/dashboard/templates/dashboard/base.html" afterPath="$PROJECT_DIR$/circle/dashboard/templates/dashboard/base.html" />
<change beforePath="$PROJECT_DIR$/circle/network/templates/network/editor.html" afterPath="$PROJECT_DIR$/circle/network/templates/network/editor.html" />
<change beforePath="$PROJECT_DIR$/circle/network/urls.py" afterPath="$PROJECT_DIR$/circle/network/urls.py" />
<change beforePath="$PROJECT_DIR$/circle/network/views.py" afterPath="$PROJECT_DIR$/circle/network/views.py" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" />
......@@ -31,23 +50,43 @@
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="console.html" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail/console.html">
<file leaf-file-name="views.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/circle/network/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="374">
<caret line="43" column="65" lean-forward="false" selection-start-line="43" selection-start-column="65" selection-end-line="43" selection-end-column="65" />
<state relative-caret-position="455">
<caret line="1070" column="8" lean-forward="false" selection-start-line="1070" selection-start-column="8" selection-end-line="1070" selection-end-column="8" />
<folding>
<element signature="n#style#0;n#iframe#0;n#!!top" expanded="true" />
<element signature="e#732#743#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="local.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/circle/circle/settings/local.py">
<file leaf-file-name="editor.html" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/editor.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="22" lean-forward="false" selection-start-line="0" selection-start-column="22" selection-end-line="0" selection-end-column="22" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="base.html" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/base.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="151">
<caret line="34" column="20" lean-forward="true" selection-start-line="34" selection-start-column="20" selection-end-line="34" selection-end-column="20" />
<state relative-caret-position="17">
<caret line="40" column="52" lean-forward="true" selection-start-line="40" selection-start-column="52" selection-end-line="40" selection-end-column="52" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="vm-detail.html" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
......@@ -56,8 +95,8 @@
<file leaf-file-name="vm.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/circle/dashboard/views/vm.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="450">
<caret line="126" column="28" lean-forward="false" selection-start-line="126" selection-start-column="28" selection-end-line="126" selection-end-column="28" />
<state relative-caret-position="161">
<caret line="112" column="17" lean-forward="false" selection-start-line="112" selection-start-column="17" selection-end-line="112" selection-end-column="17" />
<folding>
<element signature="e#40144#41315#0" expanded="false" />
</folding>
......@@ -65,6 +104,16 @@
</provider>
</entry>
</file>
<file leaf-file-name="base.html" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/base.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="102">
<caret line="6" column="8" lean-forward="true" selection-start-line="6" selection-start-column="8" selection-end-line="6" selection-end-column="8" />
<folding />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FileTemplateManagerImpl">
......@@ -77,24 +126,12 @@
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>priority_choices</find>
<find>plain</find>
<find>asd</find>
<find>vmcreat</find>
<find>customize</find>
<find>custom</find>
<find>customized</find>
<find>policy</find>
<find>profile</find>
<find>@profiler.trace</find>
<find>vmdetail</find>
<find>create(</find>
<find>pk</find>
<find>get_ab</find>
<find>vmdeta</find>
<find>instanc</find>
<find>[a-z0-9-]+</find>
<find>network</find>
<find>(?P&lt;pk&gt;[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})</find>
<find>initial</find>
<find>ini</find>
......@@ -107,11 +144,24 @@
<find>create</find>
<find>vnc</find>
<find>c</find>
<find>span</find>
<find>network</find>
<find>static</find>
<find>{% javascript</find>
<find>datastore</find>
<find>horizon/client_side/</find>
<find>jstemplate</find>
<find>tag</find>
<find>editor.</find>
<find>editorvi</find>
<find>balloon</find>
<find>trans</find>
</findStrings>
<replaceStrings>
<replace>'ACTIVE'</replace>
<replace>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}</replace>
<replace>&lt;pk:slug&gt;</replace>
<replace>network/horizon/client_side/</replace>
</replaceStrings>
</component>
<component name="Git.Settings">
......@@ -120,30 +170,13 @@
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/circle/dashboard/templates/dashboard/base.html" />
<option value="$PROJECT_DIR$/circle/vm/managers/os_instance_manager.py" />
<option value="$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail/home.html" />
<option value="$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail/access.html" />
<option value="$PROJECT_DIR$/circle/dashboard/views/__init__.py" />
<option value="$PROJECT_DIR$/circle/openstack_api/glance.py" />
<option value="$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail.html" />
<option value="$PROJECT_DIR$/circle/acl/models.py" />
<option value="$PROJECT_DIR$/circle/circle/os_policies/neutron_policy.json" />
<option value="$PROJECT_DIR$/circle/circle/os_policies/cinder_policy.json" />
<option value="$PROJECT_DIR$/circle/circle/os_policies/glance_policy.json" />
<option value="$PROJECT_DIR$/circle/circle/os_policies/keystone_policy.json" />
<option value="$PROJECT_DIR$/circle/openstack_auth/__init__.py" />
<option value="$PROJECT_DIR$/circle/circle/os_policies/nova_policy.json" />
<option value="$PROJECT_DIR$/circle/common/operations.py" />
<option value="$PROJECT_DIR$/circle/vm/models/common.py" />
<option value="$PROJECT_DIR$/circle/firewall/models.py" />
<option value="$PROJECT_DIR$/circle/dashboard/models.py" />
<option value="$PROJECT_DIR$/circle/circle/settings/base.py" />
<option value="$PROJECT_DIR$/circle/vm/operations.py" />
<option value="$PROJECT_DIR$/circle/dashboard/templates/dashboard/index.html" />
<option value="$PROJECT_DIR$/circle/circle/urls.py" />
<option value="$PROJECT_DIR$/circle/common/views.py" />
<option value="$PROJECT_DIR$/circle/network/templates/network/editor.html" />
<option value="$PROJECT_DIR$/circle/circle/settings/static_and_pipeline.py" />
<option value="$PROJECT_DIR$/circle/dashboard/templates/auth/login.html" />
<option value="$PROJECT_DIR$/circle/storage/models.py" />
......@@ -161,9 +194,7 @@
<option value="$PROJECT_DIR$/circle/dashboard/templates/dashboard/index-vxlans.html" />
<option value="$PROJECT_DIR$/circle/openstack_api/base.py" />
<option value="$PROJECT_DIR$/circle/dashboard/urls.py" />
<option value="$PROJECT_DIR$/circle/network/urls.py" />
<option value="$PROJECT_DIR$/circle/network/forms.py" />
<option value="$PROJECT_DIR$/circle/network/views.py" />
<option value="$PROJECT_DIR$/circle/network/templates/network/vxlan-create.html" />
<option value="$PROJECT_DIR$/circle/network/templates/network/vxlan-edit.html" />
<option value="$PROJECT_DIR$/circle/openstack_api/nova.py" />
......@@ -171,9 +202,33 @@
<option value="$PROJECT_DIR$/circle/dashboard/views/vm.py" />
<option value="$PROJECT_DIR$/circle/circle/settings/local.py" />
<option value="$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail/console.html" />
<option value="$PROJECT_DIR$/circle/dashboard/templates/dashboard/base.html" />
<option value="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_alert_message.html" />
<option value="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_confirm.html" />
<option value="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_loading_inline.html" />
<option value="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_membership.html" />
<option value="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_modal.html" />
<option value="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_progress.html" />
<option value="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_table_row.html" />
<option value="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/templates.html" />
<option value="$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_loading_modal.html" />
<option value="$PROJECT_DIR$/circle/network/templatetags/horizon.py" />
<option value="$PROJECT_DIR$/circle/network/templatetags/__init__.py" />
<option value="$PROJECT_DIR$/circle/bower.json" />
<option value="$PROJECT_DIR$/circle/circle/settings/base.py" />
<option value="$PROJECT_DIR$/circle/network/static/js/horizon.networktopology.js" />
<option value="$PROJECT_DIR$/circle/network/static/js/horizon.flatnetworktopology.js" />
<option value="$PROJECT_DIR$/circle/network/urls.py" />
<option value="$PROJECT_DIR$/circle/network/templates/network/editor.html" />
<option value="$PROJECT_DIR$/circle/network/views.py" />
</list>
</option>
</component>
<component name="JsBowerSettings">
<node-interpreter value="project" />
<bower-package value="" />
<bower.json value="" />
</component>
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsGulpfileManager">
......@@ -183,8 +238,8 @@
<component name="ProjectFrameBounds">
<option name="x" value="-2" />
<option name="y" value="-1" />
<option name="width" value="1370" />
<option name="height" value="751" />
<option name="width" value="1924" />
<option name="height" value="1063" />
</component>
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
......@@ -257,15 +312,6 @@
<item name="templates" type="462c0819:PsiDirectoryNode" />
<item name="dashboard" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="cloud" type="b2602c69:ProjectViewProjectNode" />
<item name="cloud" type="462c0819:PsiDirectoryNode" />
<item name="circle" type="462c0819:PsiDirectoryNode" />
<item name="dashboard" type="462c0819:PsiDirectoryNode" />
<item name="templates" type="462c0819:PsiDirectoryNode" />
<item name="dashboard" type="462c0819:PsiDirectoryNode" />
<item name="vm-detail" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
......@@ -279,7 +325,7 @@
<property name="settings.editor.selected.configurable" value="preferences.sourceCode.HTML" />
<property name="NewWatcherDialog.advanced.open" value="true" />
<property name="DefaultHtmlFileTemplate" value="HTML File" />
<property name="SearchEverywhereHistoryKey" value="local&#9;null&#9;null&#10;vmdeta&#9;null&#9;null&#10;index&#9;null&#9;null&#10;vnc&#9;null&#9;null&#10;plain&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/vm-plain-image-create.html&#10;forms&#9;null&#9;null&#10;vxlanform&#9;null&#9;null&#10;instanc&#9;FILE&#9;file:///home/h3yduck/cloud/circle/vm/models/instance.py&#10;index-vxla&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/index-vxlans.html&#10;instance&#9;FILE&#9;file:///home/h3yduck/cloud/circle/vm/models/instance.py&#10;_vm-c&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/_vm-create-1.html&#10;vmcrea&#9;null&#9;null&#10;loginV&#9;null&#9;null&#10;index.html&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/index.html&#10;sleep&#9;null&#9;null&#10;Deploy&#9;null&#9;null&#10;Instance&#9;null&#9;null&#10;Vmdeta&#9;null&#9;null&#10;list_from&#9;null&#9;null&#10;aclupda&#9;null&#9;null&#10;base.htm&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/base.html&#10;method&#9;ACTION&#9;GoToMenuEx&#10;base.ht&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/base.html&#10;base.html&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/base.html&#10;index.py&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/views/index.py&#10;index.htm&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/index.html&#10;server&#9;null&#9;null&#10;Disk&#9;null&#9;null" />
<property name="SearchEverywhereHistoryKey" value="vmdetailv&#9;null&#9;null&#10;editor&#9;null&#9;null&#10;networktopo&#9;FILE&#9;file:///home/h3yduck/cloud/circle/network/static/js/horizon.networktopology.js&#10;bow&#9;FILE&#9;file:///home/h3yduck/cloud/circle/bower.json&#10;base&#9;FILE&#9;file:///home/h3yduck/cloud/circle/circle/settings/base.py&#10;base.py&#9;FILE&#9;file:///home/h3yduck/cloud/circle/circle/settings/base.py&#10;local&#9;null&#9;null&#10;vmdeta&#9;null&#9;null&#10;index&#9;null&#9;null&#10;vnc&#9;null&#9;null&#10;plain&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/vm-plain-image-create.html&#10;forms&#9;null&#9;null&#10;vxlanform&#9;null&#9;null&#10;instanc&#9;FILE&#9;file:///home/h3yduck/cloud/circle/vm/models/instance.py&#10;index-vxla&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/index-vxlans.html&#10;instance&#9;FILE&#9;file:///home/h3yduck/cloud/circle/vm/models/instance.py&#10;_vm-c&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/_vm-create-1.html&#10;vmcrea&#9;null&#9;null&#10;loginV&#9;null&#9;null&#10;index.html&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/index.html&#10;sleep&#9;null&#9;null&#10;Deploy&#9;null&#9;null&#10;Instance&#9;null&#9;null&#10;Vmdeta&#9;null&#9;null&#10;list_from&#9;null&#9;null&#10;aclupda&#9;null&#9;null&#10;base.htm&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/base.html&#10;method&#9;ACTION&#9;GoToMenuEx&#10;base.ht&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/base.html&#10;base.html&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/base.html&#10;index.py&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/views/index.py&#10;index.htm&#9;FILE&#9;file:///home/h3yduck/cloud/circle/dashboard/templates/dashboard/index.html&#10;server&#9;null&#9;null&#10;Disk&#9;null&#9;null" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
......@@ -377,7 +423,7 @@
</todo-panel>
</component>
<component name="ToolWindowManager">
<frame x="-2" y="-1" width="1370" height="751" extended-state="0" />
<frame x="-2" y="-1" width="1924" height="1063" extended-state="0" />
<editor active="true" />
<layout>
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32980973" sideWeight="0.4978701" order="6" side_tool="false" content_ui="tabs" />
......@@ -386,20 +432,20 @@
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3280757" sideWeight="0.5234139" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.43023255" sideWeight="0.43610224" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Coverage" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.3280757" sideWeight="0.4765861" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.23036253" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.5021142" sideWeight="0.46676737" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.21991481" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<window_info id="Docker" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32980973" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="SciView" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.24921136" sideWeight="0.5511182" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.2780127" sideWeight="0.5332326" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32980973" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
</layout>
<layout-to-restore>
......@@ -476,7 +522,7 @@
</properties>
</breakpoint>
</default-breakpoints>
<option name="time" value="163" />
<option name="time" value="173" />
</breakpoint-manager>
<watches-manager />
</component>
......@@ -509,476 +555,484 @@
</expressions>
<expressions id="evaluateExpression">
<expression>
<expression-string>openstack_api.nova.server_vnc_console(self.request, instance.os_server_id)</expression-string>
<expression-string>self._get_networks(request)</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
<expression>
<expression-string>openstack_api.nova.server_vnc_console(self.request)</expression-string>
<expression-string>self._get_servers(request)</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
<expression>
<expression-string>instance</expression-string>
<language-id>Python</language-id>
<expression-string>{% javascript &quot;horizon.networktopology&quot; %}</expression-string>
<language-id>HTML</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
<expression>
<expression-string>form.cleaned_data</expression-string>
<expression-string>openstack_api.nova.server_vnc_console(self.request, instance.os_server_id)</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
<expression>
<expression-string>form['name']</expression-string>
<expression-string>openstack_api.nova.server_vnc_console(self.request)</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
<expression>
<expression-string>form.name</expression-string>
<expression-string>instance</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
<expression>
<expression-string>form.fields.name</expression-string>
<expression-string>form.cleaned_data</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
<expression>
<expression-string>form.fields['name']</expression-string>
<expression-string>form['name']</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
<expression>
<expression-string>context[u'object'].id</expression-string>
<expression-string>form.name</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
</expressions>
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/index.html">
<entry file="file://$PROJECT_DIR$/circle/dashboard/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="306">
<caret line="18" column="36" lean-forward="false" selection-start-line="18" selection-start-column="36" selection-end-line="18" selection-end-column="36" />
<state relative-caret-position="17">
<caret line="52" column="23" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="238" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/request/models.py">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/index-vxlans.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="194">
<caret line="63" column="6" lean-forward="false" selection-start-line="63" selection-start-column="6" selection-end-line="63" selection-end-column="6" />
<state relative-caret-position="204">
<caret line="15" column="49" lean-forward="false" selection-start-line="15" selection-start-column="47" selection-end-line="15" selection-end-column="49" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/views/storage.py">
<entry file="file://$PROJECT_DIR$/circle/network/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
<state relative-caret-position="465">
<caret line="78" column="63" lean-forward="false" selection-start-line="78" selection-start-column="60" selection-end-line="78" selection-end-column="63" />
<folding>
<element signature="e#731#751#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/storage/models.py">
<entry file="file://$PROJECT_DIR$/circle/openstack_api/base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="163">
<caret line="120" column="0" lean-forward="false" selection-start-line="120" selection-start-column="0" selection-end-line="120" selection-end-column="0" />
<state relative-caret-position="126">
<caret line="139" column="27" lean-forward="false" selection-start-line="139" selection-start-column="21" selection-end-line="139" selection-end-column="27" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/_template-create.html">
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/views/generic/edit.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="15" lean-forward="true" selection-start-line="0" selection-start-column="15" selection-end-line="1" selection-end-column="28" />
<state relative-caret-position="202">
<caret line="198" column="6" lean-forward="false" selection-start-line="198" selection-start-column="6" selection-end-line="198" selection-end-column="6" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/openstack_api/glance.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/rule-create.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-1581">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/views/template.py">
<entry file="file://$PROJECT_DIR$/circle/dashboard/forms.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-90">
<caret line="105" column="22" lean-forward="false" selection-start-line="105" selection-start-column="22" selection-end-line="105" selection-end-column="22" />
<state relative-caret-position="212">
<caret line="1702" column="27" lean-forward="false" selection-start-line="1702" selection-start-column="27" selection-end-line="1702" selection-end-column="27" />
<folding>
<marker date="1518171677270" expanded="true" signature="9976:10189" ph="SELECT count... vm_instance" />
<element signature="e#732#770#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/forms/forms.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/vxlan-create.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="366">
<caret line="509" column="6" lean-forward="false" selection-start-line="509" selection-start-column="6" selection-end-line="509" selection-end-column="6" />
<state relative-caret-position="255">
<caret line="15" column="23" lean-forward="true" selection-start-line="15" selection-start-column="23" selection-end-line="15" selection-end-column="23" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/views/generic/base.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/vxlan-edit.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="195">
<caret line="87" column="0" lean-forward="false" selection-start-line="87" selection-start-column="0" selection-end-line="87" selection-end-column="0" />
<state relative-caret-position="272">
<caret line="16" column="24" lean-forward="true" selection-start-line="16" selection-start-column="24" selection-end-line="16" selection-end-column="24" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/nojs-wrapper.html">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-plain-image-create.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="3" selection-end-column="19" />
<state relative-caret-position="119">
<caret line="7" column="2" lean-forward="false" selection-start-line="7" selection-start-column="2" selection-end-line="16" selection-end-column="9" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/_vm-create-1.html">
<entry file="file://$PROJECT_DIR$/circle/openstack_api/nova.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="391">
<caret line="95" column="34" lean-forward="false" selection-start-line="95" selection-start-column="34" selection-end-line="95" selection-end-column="34" />
<folding>
<element signature="n#style#0;n#a#0;n#div#1;n#div#0;n#!!top" expanded="true" />
</folding>
<state relative-caret-position="202">
<caret line="70" column="6" lean-forward="false" selection-start-line="70" selection-start-column="6" selection-end-line="70" selection-end-column="6" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/circle/os_policies/keystone_policy.json">
<entry file="file://$PROJECT_DIR$/circle/network/forms.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="425">
<caret line="61" column="39" lean-forward="false" selection-start-line="61" selection-start-column="39" selection-end-line="61" selection-end-column="39" />
<folding />
<state relative-caret-position="210">
<caret line="366" column="24" lean-forward="true" selection-start-line="366" selection-start-column="24" selection-end-line="366" selection-end-column="24" />
<folding>
<element signature="e#732#775#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/circle/os_policies/nova_policy.json">
<entry file="file://$PROJECT_DIR$/circle/dashboard/views/index.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="298">
<caret line="37" column="56" lean-forward="false" selection-start-line="37" selection-start-column="56" selection-end-line="37" selection-end-column="56" />
<state relative-caret-position="95">
<caret line="129" column="0" lean-forward="true" selection-start-line="129" selection-start-column="0" selection-end-line="129" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/_vm-create-2.html">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail/console.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="425">
<caret line="25" column="31" lean-forward="false" selection-start-line="25" selection-start-column="31" selection-end-line="26" selection-end-column="17" />
<folding />
<state relative-caret-position="374">
<caret line="43" column="65" lean-forward="false" selection-start-line="43" selection-start-column="65" selection-end-line="43" selection-end-column="65" />
<folding>
<element signature="n#style#0;n#iframe#0;n#!!top" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/openstack_auth/policy.py">
<entry file="file://$PROJECT_DIR$/circle/circle/settings/local.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="126">
<caret line="23" column="0" lean-forward="false" selection-start-line="23" selection-start-column="0" selection-end-line="23" selection-end-column="0" />
<state relative-caret-position="202">
<caret line="37" column="34" lean-forward="false" selection-start-line="37" selection-start-column="34" selection-end-line="37" selection-end-column="34" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/openstack_api/policy.py">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/storage/detail.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="34">
<caret line="14" column="18" lean-forward="false" selection-start-line="14" selection-start-column="18" selection-end-line="14" selection-end-column="18" />
<state relative-caret-position="251">
<caret line="147" column="30" lean-forward="false" selection-start-line="147" selection-start-column="30" selection-end-line="147" selection-end-column="30" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py">
<entry file="file://$PROJECT_DIR$/circle/bower_components/hogan.js/lib/compiler.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="126">
<caret line="124" column="0" lean-forward="false" selection-start-line="124" selection-start-column="0" selection-end-line="124" selection-end-column="0" />
<folding />
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="n#!!doc" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/utils/datastructures.py">
<entry file="file://$PROJECT_DIR$/circle/bower_components/hogan.js/lib/template.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="126">
<caret line="125" column="0" lean-forward="false" selection-start-line="125" selection-start-column="0" selection-end-line="125" selection-end-column="0" />
<folding />
<state relative-caret-position="-4921">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="n#!!doc" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/novaclient/v2/servers.py">
<entry file="file://$PROJECT_DIR$/circle/bower_components/hogan.js/web/1.0.0/hogan.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="262">
<caret line="1221" column="51" lean-forward="false" selection-start-line="1221" selection-start-column="51" selection-end-line="1221" selection-end-column="51" />
<folding />
<state relative-caret-position="-8001">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="n#!!doc" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/models.py">
<entry file="file://$PROJECT_DIR$/circle/bower_components/hogan.js/web/builds/3.0.2/hogan-3.0.2.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="182">
<caret line="359" column="40" lean-forward="true" selection-start-line="359" selection-start-column="40" selection-end-line="359" selection-end-column="40" />
<folding />
<state relative-caret-position="-306">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="n#!!doc" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/db/models/base.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_alert_message.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="126">
<caret line="474" column="0" lean-forward="false" selection-start-line="474" selection-start-column="0" selection-end-line="474" selection-end-column="0" />
<state relative-caret-position="0">
<caret line="0" column="20" lean-forward="false" selection-start-line="0" selection-start-column="20" selection-end-line="0" selection-end-column="20" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/common/operations.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_confirm.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-233">
<caret line="159" column="6" lean-forward="false" selection-start-line="159" selection-start-column="6" selection-end-line="159" selection-end-column="6" />
<state relative-caret-position="0">
<caret line="0" column="20" lean-forward="false" selection-start-line="0" selection-start-column="20" selection-end-line="0" selection-end-column="20" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/views/generic/detail.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_loading_inline.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="126">
<caret line="21" column="8" lean-forward="false" selection-start-line="21" selection-start-column="8" selection-end-line="21" selection-end-column="8" />
<state relative-caret-position="0">
<caret line="0" column="20" lean-forward="false" selection-start-line="0" selection-start-column="20" selection-end-line="0" selection-end-column="20" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/request/urls.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_progress.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="601">
<caret line="61" column="161" lean-forward="false" selection-start-line="61" selection-start-column="161" selection-end-line="61" selection-end-column="161" />
<state relative-caret-position="0">
<caret line="0" column="20" lean-forward="false" selection-start-line="0" selection-start-column="20" selection-end-line="0" selection-end-column="20" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/views/util.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_table_row.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="206">
<caret line="242" column="0" lean-forward="false" selection-start-line="242" selection-start-column="0" selection-end-line="242" selection-end-column="0" />
<state relative-caret-position="0">
<caret line="0" column="20" lean-forward="false" selection-start-line="0" selection-start-column="20" selection-end-line="0" selection-end-column="20" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/index-vm.html">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/template.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="230">
<caret line="95" column="36" lean-forward="true" selection-start-line="95" selection-start-column="36" selection-end-line="95" selection-end-column="36" />
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/openstack_api/__init__.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_modal.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="284">
<caret line="38" column="0" lean-forward="false" selection-start-line="38" selection-start-column="0" selection-end-line="38" selection-end-column="0" />
<state relative-caret-position="68">
<caret line="4" column="0" lean-forward="true" selection-start-line="4" selection-start-column="0" selection-end-line="4" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/vm/models/network.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_membership.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="986">
<caret line="69" column="6" lean-forward="false" selection-start-line="69" selection-start-column="6" selection-end-line="69" selection-end-column="6" />
<state relative-caret-position="0">
<caret line="0" column="20" lean-forward="false" selection-start-line="0" selection-start-column="20" selection-end-line="0" selection-end-column="20" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/vm/models/instance.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_script_loader.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="214">
<caret line="52" column="25" lean-forward="false" selection-start-line="52" selection-start-column="25" selection-end-line="52" selection-end-column="25" />
<state relative-caret-position="340">
<caret line="20" column="0" lean-forward="true" selection-start-line="20" selection-start-column="0" selection-end-line="20" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/forms/models.py">
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/template/loaders/base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="126">
<caret line="294" column="0" lean-forward="false" selection-start-line="294" selection-start-column="0" selection-end-line="294" selection-end-column="0" />
<state relative-caret-position="284">
<caret line="39" column="0" lean-forward="false" selection-start-line="39" selection-start-column="0" selection-end-line="39" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/braces/views/_access.py">
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/template/base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="202">
<caret line="87" column="6" lean-forward="false" selection-start-line="87" selection-start-column="6" selection-end-line="87" selection-end-column="6" />
<state relative-caret-position="1109">
<caret line="229" column="0" lean-forward="false" selection-start-line="229" selection-start-column="0" selection-end-line="229" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/contrib/messages/views.py">
<entry file="file://$PROJECT_DIR$/circle/network/__init__.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="272">
<caret line="16" column="27" lean-forward="false" selection-start-line="16" selection-start-column="8" selection-end-line="16" selection-end-column="27" />
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/urls.py">
<entry file="file://$PROJECT_DIR$/circle/network/templatetags/__init__.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="17">
<caret line="52" column="23" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="238" selection-end-column="0" />
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/index-vxlans.html">
<entry file="file://$PROJECT_DIR$/circle/bower.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204">
<caret line="15" column="49" lean-forward="false" selection-start-line="15" selection-start-column="47" selection-end-line="15" selection-end-column="49" />
<state relative-caret-position="476">
<caret line="28" column="21" lean-forward="false" selection-start-line="28" selection-start-column="21" selection-end-line="28" selection-end-column="21" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/network/models.py">
<entry file="file://$PROJECT_DIR$/circle/circle/settings/base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="465">
<caret line="78" column="63" lean-forward="false" selection-start-line="78" selection-start-column="60" selection-end-line="78" selection-end-column="63" />
<folding>
<element signature="e#731#751#0" expanded="false" />
</folding>
<state relative-caret-position="284">
<caret line="260" column="35" lean-forward="true" selection-start-line="260" selection-start-column="35" selection-end-line="260" selection-end-column="35" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/openstack_api/base.py">
<entry file="file://$PROJECT_DIR$/circle/openstack_api/network.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="126">
<caret line="139" column="27" lean-forward="false" selection-start-line="139" selection-start-column="21" selection-end-line="139" selection-end-column="27" />
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.virtualenvs/cloud/local/lib/python2.7/site-packages/django/views/generic/edit.py">
<entry file="file://$PROJECT_DIR$/circle/openstack_api/neutron.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="202">
<caret line="198" column="6" lean-forward="false" selection-start-line="198" selection-start-column="6" selection-end-line="198" selection-end-column="6" />
<state relative-caret-position="255">
<caret line="1100" column="23" lean-forward="false" selection-start-line="1100" selection-start-column="23" selection-end-line="1100" selection-end-column="23" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/rule-create.html">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/_loading_modal.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<state relative-caret-position="289">
<caret line="17" column="0" lean-forward="false" selection-start-line="17" selection-start-column="0" selection-end-line="17" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/forms.py">
<entry file="file://$PROJECT_DIR$/circle/network/templatetags/horizon.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="212">
<caret line="1702" column="27" lean-forward="false" selection-start-line="1702" selection-start-column="27" selection-end-line="1702" selection-end-column="27" />
<state relative-caret-position="561">
<caret line="33" column="7" lean-forward="false" selection-start-line="33" selection-start-column="7" selection-end-line="33" selection-end-column="7" />
<folding>
<element signature="e#732#770#0" expanded="false" />
<element signature="e#605#643#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/network/urls.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/horizon/client_side/templates.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="227">
<caret line="137" column="0" lean-forward="false" selection-start-line="137" selection-start-column="0" selection-end-line="137" selection-end-column="0" />
<folding>
<element signature="e#732#764#0" expanded="true" />
</folding>
<state relative-caret-position="68">
<caret line="4" column="54" lean-forward="false" selection-start-line="4" selection-start-column="54" selection-end-line="4" selection-end-column="54" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/network/views.py">
<entry file="file://$PROJECT_DIR$/circle/network/static/js/horizon.loader.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="272">
<caret line="1000" column="23" lean-forward="false" selection-start-line="1000" selection-start-column="23" selection-end-line="1000" selection-end-column="23" />
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#732#746#0" expanded="true" />
<element signature="n#!!doc" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/vxlan-create.html">
<entry file="file://$PROJECT_DIR$/circle/network/static/js/horizon.networktopologycommon.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="255">
<caret line="15" column="23" lean-forward="true" selection-start-line="15" selection-start-column="23" selection-end-line="15" selection-end-column="23" />
<state relative-caret-position="544">
<caret line="47" column="39" lean-forward="false" selection-start-line="47" selection-start-column="24" selection-end-line="47" selection-end-column="39" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/openstack_api/neutron.py">
<entry file="file://$PROJECT_DIR$/circle/network/static/js/horizon.networktopology.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-3">
<caret line="1053" column="26" lean-forward="false" selection-start-line="1053" selection-start-column="26" selection-end-line="1053" selection-end-column="26" />
<folding>
<element signature="e#804#842#0" expanded="true" />
</folding>
<state relative-caret-position="828">
<caret line="113" column="49" lean-forward="true" selection-start-line="113" selection-start-column="49" selection-end-line="113" selection-end-column="49" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/vxlan-edit.html">
<entry file="file://$PROJECT_DIR$/circle/network/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="272">
<caret line="16" column="24" lean-forward="true" selection-start-line="16" selection-start-column="24" selection-end-line="16" selection-end-column="24" />
<state relative-caret-position="420">
<caret line="130" column="79" lean-forward="true" selection-start-line="130" selection-start-column="79" selection-end-line="130" selection-end-column="79" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-plain-image-create.html">
<entry file="file://$PROJECT_DIR$/circle/network/static/js/horizon.flatnetworktopology.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="119">
<caret line="7" column="2" lean-forward="false" selection-start-line="7" selection-start-column="2" selection-end-line="16" selection-end-column="9" />
<folding />
<state relative-caret-position="709">
<caret line="92" column="53" lean-forward="false" selection-start-line="92" selection-start-column="53" selection-end-line="92" selection-end-column="53" />
<folding>
<element signature="n#!!doc" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/openstack_api/nova.py">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/base.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="202">
<caret line="70" column="6" lean-forward="false" selection-start-line="70" selection-start-column="6" selection-end-line="70" selection-end-column="6" />
<state relative-caret-position="102">
<caret line="6" column="8" lean-forward="true" selection-start-line="6" selection-start-column="8" selection-end-line="6" selection-end-column="8" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/network/forms.py">
<entry file="file://$PROJECT_DIR$/circle/network/templates/network/editor.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="210">
<caret line="366" column="24" lean-forward="true" selection-start-line="366" selection-start-column="24" selection-end-line="366" selection-end-column="24" />
<folding>
<element signature="e#732#775#0" expanded="true" />
</folding>
<state relative-caret-position="0">
<caret line="0" column="22" lean-forward="false" selection-start-line="0" selection-start-column="22" selection-end-line="0" selection-end-column="22" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/views/index.py">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="95">
<caret line="129" column="0" lean-forward="true" selection-start-line="129" selection-start-column="0" selection-end-line="129" selection-end-column="0" />
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/views/vm.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="450">
<caret line="126" column="28" lean-forward="false" selection-start-line="126" selection-start-column="28" selection-end-line="126" selection-end-column="28" />
<state relative-caret-position="161">
<caret line="112" column="17" lean-forward="false" selection-start-line="112" selection-start-column="17" selection-end-line="112" selection-end-column="17" />
<folding>
<element signature="e#40144#41315#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/circle/settings/local.py">
<entry file="file://$PROJECT_DIR$/circle/network/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="151">
<caret line="34" column="20" lean-forward="true" selection-start-line="34" selection-start-column="20" selection-end-line="34" selection-end-column="20" />
<folding />
<state relative-caret-position="455">
<caret line="1070" column="8" lean-forward="false" selection-start-line="1070" selection-start-column="8" selection-end-line="1070" selection-end-column="8" />
<folding>
<element signature="e#732#743#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/vm-detail/console.html">
<entry file="file://$PROJECT_DIR$/circle/dashboard/templates/dashboard/base.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="374">
<caret line="43" column="65" lean-forward="false" selection-start-line="43" selection-start-column="65" selection-end-line="43" selection-end-column="65" />
<folding>
<element signature="n#style#0;n#iframe#0;n#!!top" expanded="true" />
</folding>
<state relative-caret-position="17">
<caret line="40" column="52" lean-forward="true" selection-start-line="40" selection-start-column="52" selection-end-line="40" selection-end-column="52" />
<folding />
</state>
</provider>
</entry>
......
......@@ -23,6 +23,9 @@
"datatables": "~1.10.4",
"chart.js": "2.3.0",
"clipboard": "~1.6.1",
"jsPlumb": "2.5.7"
"jsPlumb": "2.5.7",
"d3": "3.5.16",
"hogan.js": "hogan#^3.0.2",
"angular": "1.5.8"
}
}
......@@ -253,6 +253,19 @@ PIPELINE = {
),
"output_filename": "datastore.js",
},
"editor": {"source_filenames": (
"d3/d3.js",
"hogan.js/web/builds/2.0.0/hogan-2.0.0.js",
"angular/angular.min.js",
"js/horizon.js",
"js/horizon.loader.js",
"js/horizon.templates.js",
"js/horizon.flatnetworktopology.js",
"js/horizon.networktopology.js",
"js/horizon.networktopologycommon.js",
),
"output_filename": "editor.js",
},
},
}
......
......@@ -13,7 +13,7 @@
{% block navbar %}
{% if view.request.user.is_authenticated and view.request.user.pk and not view.request.token_user %}
<span id="user-options" data-desktop_notifications="{{ request.user.profile.desktop_notifications }}"><span>
<span id="user-options" data-desktop_notifications="{{ request.user.profile.desktop_notifications }}"></span>
<ul class="nav navbar-nav navbar-right" id="dashboard-menu">
{% if request.user.is_superuser %}
......
......@@ -88,9 +88,9 @@ horizon.flat_network_topology = {
return;
}
self.color = d3.scale.category10();
self.balloon_tmpl = Hogan.compile($('#balloon_container').html());
self.balloon_device_tmpl = Hogan.compile($('#balloon_device').html());
self.balloon_port_tmpl = Hogan.compile($('#balloon_port').html());
self.balloon_tmpl = '<span>balloon_tmpl</span>'
self.balloon_device_tmpl = '<span>balloon_device_tmpl</span>'
self.balloon_port_tmpl = '<span>balloon_port_tmpl</span>'
$(document)
.on('click', 'a.closeTopologyBalloon', function(e) {
......
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
/* This is the base Horizon JavaScript object. There is only ever one of these
* loaded (referenced as horizon with a lower-case h) which happens immediately
* after the definition below.
*
* Scripts that are dependent on functionality defined in the Horizon object
* must be included after this script in templates/base.html.
*/
var Horizon = function () {
var horizon = {},
initFunctions = [];
/* Use the addInitFunction() function to add initialization code which must
* be called on DOM ready. This is useful for adding things like event
* handlers or any other initialization functions which should precede user
* interaction but rely on DOM readiness.
*/
horizon.addInitFunction = function (fn) {
initFunctions.push(fn);
};
/* Call all initialization functions and clear the queue. */
horizon.init = function () {
for (var i = 0; i < initFunctions.length; i += 1) {
initFunctions[i]();
}
// Prevent multiple executions, just in case.
initFunctions = [];
};
/* Storage for backend configuration variables which the frontend
* should be aware of.
*/
horizon.conf = {};
// default languageCode for tests that run without Django context
horizon.languageCode = 'en';
return horizon;
};
// Create the one and only horizon object.
/*eslint-disable no-unused-vars */
var horizon = new Horizon();
/*eslint-enable no-unused-vars */
/*
Simple loader rendering logic
*/
horizon.loader = {
templates: {
inline: '#loader-inline',
modal: '#loader-modal'
}
};
horizon.loader.inline = function(text) {
return horizon.templates.compile(horizon.loader.templates.inline, {text: text});
};
horizon.loader.modal = function(text) {
return horizon.templates.compile(horizon.loader.templates.modal, {text: text});
};
......@@ -111,11 +111,11 @@ horizon.network_topology = {
self.data.ports = {};
// Setup balloon popups
self.balloonTmpl = Hogan.compile(angular.element('#balloon_container').html());
self.balloon_deviceTmpl = Hogan.compile(angular.element('#balloon_device').html());
self.balloon_portTmpl = Hogan.compile(angular.element('#balloon_port').html());
self.balloon_netTmpl = Hogan.compile(angular.element('#balloon_net').html());
self.balloon_instanceTmpl = Hogan.compile(angular.element('#balloon_instance').html());
self.balloonTmpl = "<span>balloonTmpl</span>"
self.balloon_deviceTmpl = "<span>balloon_deviceTmpl</span>"
self.balloon_portTmpl = "<span>balloon_portTmpl</span>"
self.balloon_netTmpl = "<span>balloon_netTmpl</span>"
self.balloon_instanceTmpl = "<span>balloon_instanceTmpl</span>"
angular.element(document)
.on('click', 'a.closeTopologyBalloon', function(e) {
......
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
/* global Hogan */
/* Namespace for core functionality related to client-side templating. */
horizon.templates = {
template_ids: [
"#modal_template",
"#empty_row_template",
"#alert_message_template",
"#loader-modal",
"#loader-inline",
"#membership_template",
"#confirm_modal",
"#progress-modal"
],
compiled_templates: {}
};
/* Pre-loads and compiles the client-side templates. */
horizon.templates.compile_templates = function (id) {
// If an id is passed in, only compile that template
if (id) {
horizon.templates.compiled_templates[id] = Hogan.compile($(id).html());
} else {
// If its never been set, make it an empty object
horizon.templates.compiled_templates =
$.isEmptyObject(horizon.templates.compiled_templates) ? {} : horizon.templates.compiled_templates;
// Over each template found, only recompile ones that need it
$.each(horizon.templates.template_ids, function (ind, template_id) {
if (!(template_id in horizon.templates.compiled_templates)) {
horizon.templates.compiled_templates[template_id] = Hogan.compile($(template_id).html());
}
});
}
};
/* Takes a template id, as defined in horizon.templates.template_ids, and returns the compiled
template given the context passed in, as a jQuery object
*/
horizon.templates.compile = function(id, context) {
var template = horizon.templates.compiled_templates[id];
// If its not available, maybe we didn't compile it yet, try one more time
if (!template) {
horizon.templates.compile_templates(id);
template = horizon.templates.compiled_templates[id];
}
return $(template.render(context));
};
horizon.addInitFunction(horizon.templates.init = function () {
// Load client-side template fragments and compile them.
horizon.templates.compile_templates();
});
......@@ -11,43 +11,70 @@
{% block content %}
<div class="flex-container" id="workspace">
<div class="panel panel-default text-center" id="dragPanel">
<div class="panel-heading">
<div id="workspace">
<div class="row">
<div class="col-md-9 text-left">
<h3 class="no-margin"><i class="fa fa-sitemap"></i> {% trans 'Editor' %}</h3>
</div>
<div class="col-md-3 text-right">
<button class="btn btn-success btn-xs" id="saveButton"><i class="fa fa-floppy-o"></i></button>
</div>
<div class="col-sm-12">
<div class="topology-navi">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default" id="toggle_labels_label">
<input type="checkbox" autocomplete="off" id="toggle_labels">
<span class="fa fa-th-large"></span> {% trans "Toggle Labels" %}
</label>
<label class="btn btn-default" id="toggle_networks_label">
<input type="checkbox" autocomplete="off" id="toggle_networks">
<span class="fa fa-th"></span> {% trans "Toggle Network Collapse" %}
</label>
</div>
</div>
<div class="panel-heading text-center">
<div id="filterConatiner">
<div class="row">
<input type="text" class="form-control" id="searchField" placeholder="{% trans 'Search' %}"/><br />
</div>
<div class="row">
<div class="col-md-6">
<i id="vm-filter"></i> <i class="fa fa-desktop"></i> vm
<div id="topologyCanvasContainer" class="d3-container">
<div class="nodata">
{% blocktrans trimmed %}
There are no networks, routers, or connected instances to display.
{% endblocktrans %}
</div>
<div class="col-md-6">
<i id="net-filter"></i> <i class="fa fa-sitemap"></i> net
</div>
</div>
</div>
</div>
<div class="panel-body" id="dragContainer">
</div>
<span data-networktopology="/network/editor/data" id="networktopology"></span>
<div id="topologyMessages"></div>
</div>
<div class="" id="dropContainer" oncontextmenu="return false;"></div>
{% include "network/horizon/client_side/templates.html" %}
</div>
{% endblock %}
{% block extra_js %}
{% javascript "network-editor" %}
{% javascript "editor" %}
<script type="text/javascript">
{#TODO: real cookie storage#}
var cookies = {}
horizon.cookies = {
getObject: function (x) {
return cookies[x]
}, put: function (x, y) {
cookies[x] = y
}, putObject: function (x, y) {
cookies[x] = y
}, getRaw: function (x) {
return cookies[x]
}, get: function (x) {
return cookies[x]
}
};
if (typeof horizon.network_topology !== 'undefined') {
{#TODO: this check should be false first#}
horizon.networktopologycommon.init();
horizon.flat_network_topology.init();
horizon.network_topology.init();
} else {
addHorizonLoadEvent(function () {
horizon.networktopologycommon.init();
horizon.flat_network_topology.init();
horizon.network_topology.init();
});
}
</script>
{% endblock %}
{% extends "network/horizon/client_side/template.html" %}
{% load horizon %}
{% block id %}alert_message_template{% endblock %}
{% block template %}{% spaceless %}{% jstemplate %}
<div class="alert alert-dismissable fade in alert-[[type]]">
<a class="close" data-dismiss="alert" href="#">
<span class="fa fa-times"></span>
</a>
<p>
<strong>[[type_display]]</strong>
[[#safe]]
[[[message]]]
[[/safe]]
[[^safe]]
[[message]]
[[/safe]]
</p>
</div>
{% endjstemplate %}{% endspaceless %}{% endblock %}
{% extends "network/horizon/client_side/template.html" %}
{% load i18n horizon %}
{% block id %}confirm_modal{% endblock %}
{% block template %}{% spaceless %}{% jstemplate %}
<div class="confirm-wrapper">
<span class="confirm-list">
{% blocktrans %}You have selected: [[selection]]. {% endblocktrans %}
</span>
<span class="confirm-text">{% trans 'Please confirm your selection.'%} </span>
<span class="confirm-help">[[help]]</span>
</div>
{% endjstemplate %}{% endspaceless %}{% endblock %}
{% extends "network/horizon/client_side/template.html" %}
{% load i18n horizon %}
{% block id %}loader-inline{% endblock %}
{% block template %}{% spaceless %}{% jstemplate %}
<div class="loader-inline">
<span class="loader fa fa-spinner fa-spin fa-4x text-center"></span>
<div class="loader-caption h4 text-center">[[text]]&hellip;</div>
</div>
{% endjstemplate %}{% endspaceless %}{% endblock %}
{% extends "network/horizon/client_side/template.html" %}
{% load i18n horizon %}
{% block id %}loader-modal{% endblock %}
{% block template %}{% spaceless %}{% jstemplate %}
<div class="modal loading">
<div class="modal-dialog modal-xs">
<div class="modal-content">
<div class="modal-body">
<span class="loader fa fa-spinner fa-spin fa-5x text-center"></span>
<div class="loader-caption h4 text-center">[[text]]&hellip;</div>
</div>
</div>
</div>
</div>
{% endjstemplate %}{% endspaceless %}{% endblock %}
{% extends "network/horizon/client_side/template.html" %}
{% load horizon %}
{% block id %}membership_template{% endblock %}
{% block template %}{% spaceless %}{% jstemplate %}
<ul class="nav nav-pills btn-group btn-group-sm">
<li class="member" data-[[step_slug]]-id="[[data_id]]">
<span class="display_name">[[display_name]]</span>
</li>
<li class="active"><a class="btn btn-primary" href="#add_remove">[[text]]</a></li>
<li class="dropdown role_options">
<a class="dropdown-toggle btn btn-default" data-toggle="dropdown" href="#">
<span class="roles_display">[[roles_label]]</span>
<span class="fa fa-caret-down"></span>
</a>
<ul class="dropdown-menu dropdown-menu-right role_dropdown">
[[#roles]]
<li data-role-id="[[role_id]]">
<a target="_blank">
<span class="fa fa-check"></span>
[[role_name]]
</a>
</li>
[[/roles]]
</ul>
</li>
</ul>
{% endjstemplate %}{% endspaceless %}{% endblock %}
{% extends "network/horizon/client_side/template.html" %}
{% load horizon %}
{% block id %}modal_template{% endblock %}
{% block template %}{% spaceless %}{% jstemplate %}
<div class="modal" data-backdrop="[[modal_backdrop]]">
<div class="modal-dialog">
<div class="modal-content">
<div class='modal-header'>
<a class='close' data-dismiss='modal' href="#">
<span class="fa fa-times"></span>
</a>
<h3 class="modal-title">[[title]]</h3>
</div>
<div class='modal-body'>
[[[body]]]
</div>
<div class='modal-footer'>
<a href='#' class='btn btn-default cancel' data-dismiss='modal'>[[cancel]]</a>
<a href='#' class='btn [[confirmCssClass]]'>[[confirm]]</a>
</div>
</div>
</div>
</div>
{% endjstemplate %}{% endspaceless %}{% endblock %}
{% extends "network/horizon/client_side/template.html" %}
{% load i18n horizon bootstrap %}
{% block id %}progress-modal{% endblock %}
{% block template %}{% spaceless %}{% jstemplate %}
<div class="modal loading">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-body">
<div class="modal-progress-loader">
{% bs_progress_bar 0 text="0%" %}
<div class="progress-label text-center h4">[[text]]</div>
</div>
</div>
</div>
</div>
</div>
{% endjstemplate %}{% endspaceless %}{% endblock %}
<script type="text/javascript" charset="utf-8">
/*
Added so that we can append Horizon scoped JS events to
the DOM load events without running in to the "horizon"
name-space not currently being defined since we load the
scripts at the bottom of the page.
*/
var addHorizonLoadEvent = function(func) {
var old_onload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
old_onload();
func();
}
}
}
</script>
{% extends "network/horizon/client_side/template.html" %}
{% load horizon %}
{% block id %}empty_row_template{% endblock %}
{% block template %}{% spaceless %}{% jstemplate %}
<tr class="odd empty"><td colspan="[[colspan]]">[[no_items_label]]</td></tr>
{% endjstemplate %}{% endspaceless %}{% endblock %}
<script type="text/html" id="{% block id %}{% endblock %}">{% block template %}{% endblock %}</script>
{#{% include "network/horizon/client_side/_modal.html" %}#}
{#{% include "network/horizon/client_side/_table_row.html" %}#}
{#{% include "network/horizon/client_side/_alert_message.html" %}#}
{% include "network/horizon/client_side/_loading_modal.html" %}
{% include "network/horizon/client_side/_loading_inline.html" %}
{#{% include "network/horizon/client_side/_membership.html" %}#}
{#{% include "network/horizon/client_side/_confirm.html" %}#}
{#{% include "network/horizon/client_side/_progress.html" %}#}
\ No newline at end of file
# Copyright 2012 Nebula, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import absolute_import
from django import template
register = template.Library()
class JSTemplateNode(template.Node):
"""Helper node for the ``jstemplate`` template tag."""
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context,):
output = self.nodelist.render(context)
output = output.replace('[[[', '{{{').replace(']]]', '}}}')
output = output.replace('[[', '{{').replace(']]', '}}')
output = output.replace('[%', '{%').replace('%]', '%}')
return output
@register.tag
def jstemplate(parser, token):
"""Templatetag to handle any of the Mustache-based templates.
Replaces ``[[[`` and ``]]]`` with ``{{{`` and ``}}}``,
``[[`` and ``]]`` with ``{{`` and ``}}`` and
``[%`` and ``%]`` with ``{%`` and ``%}`` to avoid conflicts
with Django's template engine when using any of the Mustache-based
templating libraries.
"""
nodelist = parser.parse(('endjstemplate',))
parser.delete_first_token()
return JSTemplateNode(nodelist)
......@@ -31,8 +31,8 @@ from .views import (
FirewallList, FirewallDetail, FirewallCreate, FirewallDelete,
remove_host_group, add_host_group,
remove_switch_port_device, add_switch_port_device,
VlanAclUpdateView, NetworkEditorView
)
VlanAclUpdateView, NetworkEditorView,
NetworkEditorDataView)
urlpatterns = [
url('^$', IndexView.as_view(), name='network.index'),
......@@ -137,8 +137,8 @@ urlpatterns = [
name="network.vxlan-delete"),
# editor
url('^editor/$', NetworkEditorView.as_view(),
name="network.editor"),
url('^editor/$', NetworkEditorView.as_view(), name="network.editor"),
url('^editor/data', NetworkEditorDataView.as_view(), name="network.editor.data"),
# non class based views
url('^hosts/(?P<pk>\d+)/remove/(?P<group_pk>\d+)/$', remove_host_group,
......
......@@ -15,55 +15,49 @@
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import logging
import random
import json
import logging
from collections import OrderedDict
from itertools import chain
from operator import itemgetter
import openstack_api
from netaddr import IPNetwork
from django.views.generic import (
TemplateView, UpdateView, DeleteView, CreateView,
DetailView)
from braces.views import LoginRequiredMixin, SuperuserRequiredMixin
from dashboard.forms import AclUserOrGroupAddForm
from dashboard.views import AclUpdateView, FormView
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.core.exceptions import (
ValidationError, PermissionDenied, ImproperlyConfigured
ValidationError
)
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, Http404
from django.db.models import Q
from django.conf import settings
from django.http import HttpResponse, Http404
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.views import View
from django.views.generic import (
TemplateView, UpdateView, DeleteView, CreateView,
DetailView)
from django_tables2 import SingleTableView
from firewall.models import (
Host, Vlan, Domain, Group, Record, BlacklistItem, Rule, VlanGroup,
SwitchPort, EthernetDevice, Firewall
)
from netaddr import IPNetwork
from network.models import Vxlan, EditorElement
from numpy.distutils.from_template import template_name_re
from openstack_api.neutron import Network
from openstack_api.utils.lazy_encoder import LazyTranslationEncoder
from vm.models import Interface, Instance
from common.views import CreateLimitedResourceMixin
from .forms import (
HostForm, VlanForm, DomainForm, GroupForm, RecordForm, BlacklistItemForm,
RuleForm, VlanGroupForm, SwitchPortForm, FirewallForm, VxlanForm)
from .tables import (
HostTable, VlanTable, SmallHostTable, DomainTable, GroupTable,
RecordTable, BlacklistItemTable, RuleTable, VlanGroupTable,
SmallRuleTable, SmallGroupRuleTable, SmallRecordTable, SwitchPortTable,
SmallDhcpTable, FirewallTable, FirewallRuleTable, VxlanTable, SmallVmTable,
)
from .forms import (
HostForm, VlanForm, DomainForm, GroupForm, RecordForm, BlacklistItemForm,
RuleForm, VlanGroupForm, SwitchPortForm, FirewallForm, VxlanForm)
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.edit import FormMixin
from django.utils.translation import ugettext_lazy as _
from braces.views import LoginRequiredMixin, SuperuserRequiredMixin
from operator import itemgetter
from itertools import chain
from dashboard.views import AclUpdateView, FormView
from dashboard.forms import AclUserOrGroupAddForm
SmallDhcpTable, FirewallTable, FirewallRuleTable, VxlanTable, )
try:
from django.http import JsonResponse
......@@ -1034,192 +1028,201 @@ class VxlanDelete(LoginRequiredMixin, DeleteView): #TODO: check user
context['confirmation'] = True
return context
class TopologyBaseTab():
def get_context_data(request, context=None):
"""Returns common context data for network topology views."""
if context is None:
context = {}
context['launch_instance_allowed'] = True
context['instance_quota_exceeded'] = False
context['create_network_allowed'] = True
context['network_quota_exceeded'] = False
context['create_router_allowed'] = True
context['router_quota_exceeded'] = False
context['console_type'] = 'VNC'
context['show_ng_launch'] = True
context['show_legacy_launch'] = True
return context
class GraphTab(TopologyBaseTab):
name = _("Graph")
slug = "graph"
preload = True
template_name = ("project/network_topology/_graph_view.html")
class NetworkEditorView(LoginRequiredMixin, TemplateView):
tab_group_class = GraphTab
template_name = 'network/editor.html'
def get(self, *args, **kwargs):
if self.request.is_ajax():
connections = self._get_connections()
ngelements = self._get_nongraph_elements(connections)
ngelements = self._serialize_elements(ngelements)
connections = map(lambda con: {
'source': 'vm-%s' % con['source'].pk,
'target': 'net-%s' % con['target'].vni,
}, connections['connections'])
unused_elements = self._get_unused_elements()
unused_elements = self._serialize_elements(unused_elements)
return JsonResponse({
'elements': map(lambda e: e.as_data(),
EditorElement.objects.filter(
owner=self.request.user)),
'nongraph_elements': ngelements,
'unused_elements': unused_elements,
'connections': connections,
})
return super(NetworkEditorView, self).get(*args, **kwargs)
def post(self, *args, **kwargs):
data = json.loads(self.request.body)
add_ifs = data.get('add_interfaces', [])
remove_ifs = data.get('remove_interfaces', [])
add_nodes = data.get('add_nodes', [])
remove_nodes = data.get('remove_nodes', [])
# Add editor element
self._element_list_operation(add_nodes, self._update_element)
# Remove editor element
self._element_list_operation(remove_nodes, self._remove_element)
# Add interface
self._interface_list_operation(add_ifs, self._add_interface)
# Remove interface
self._interface_list_operation(remove_ifs, self._remove_interface)
return self.get(*args, **kwargs)
def _max_port_num_helper(self, model, attr_name):
if not hasattr(self, attr_name):
value = model.get_objects_with_level(
'user', self.request.user).count()
setattr(self, attr_name, value)
return getattr(self, attr_name)
def get_context_data(self, **kwargs):
context = super(NetworkEditorView, self).get_context_data(**kwargs)
context['launch_instance_allowed'] = True
context['instance_quota_exceeded'] = False
context['create_network_allowed'] = True
context['network_quota_exceeded'] = False
context['create_router_allowed'] = True
context['router_quota_exceeded'] = False
context['console_type'] = 'VNC'
context['show_ng_launch'] = True
context['show_legacy_launch'] = True
@property
def vm_max_port_num(self):
return self._max_port_num_helper(Vxlan, '_vm_max_port_num')
return context
class NetworkEditorDataView(LoginRequiredMixin, View):
@property
def vxlan_max_port_num(self):
return self._max_port_num_helper(Instance, '_vxlan_max_port_num')
def _vm_serializer(self, vm):
max_port_num = self.vm_max_port_num
vxlans = Vxlan.get_objects_with_level(
'user', self.request.user).values_list('pk', flat=True)
free_port_num = max_port_num - vm.interface_set.filter(
vxlan__pk__in=vxlans).count()
return {
'name': unicode(vm),
'id': 'vm-%s' % vm.pk,
'description': vm.description,
'type': 'vm',
'icon': 'fa-desktop',
'free_port_num': free_port_num,
}
def _vxlan_serializer(self, vxlan):
max_port_num = self.vxlan_max_port_num
vms = Instance.get_objects_with_level(
'user', self.request.user).values_list('pk', flat=True)
free_port_num = max_port_num - Interface.objects.filter(
vxlan=vxlan, instance__pk__in=vms).count()
return {
'name': vxlan.name,
'id': 'net-%s' % vxlan.vni,
'description': vxlan.description,
'type': 'network',
'icon': 'fa-sitemap',
'free_port_num': free_port_num,
}
def _get_unused_elements(self):
connections = self._get_connections()
vms = map(lambda vm: vm.id, connections['vms'])
vxlans = map(lambda vxlan: vxlan.vni, connections['vxlans'])
eelems = EditorElement.objects.filter(owner=self.request.user)
vm_query = Q(pk__in=vms) | Q(editor_elements__in=eelems)
vms = Instance.get_objects_with_level(
'user', self.request.user).exclude(vm_query)
vxlan_query = Q(vni__in=vms) | Q(editor_elements__in=eelems)
vxlans = Vxlan.get_objects_with_level(
'user', self.request.user).exclude(vxlan_query)
return {
'vms': vms,
'vxlans': vxlans,
}
def _get_nongraph_elements(self, connections):
return {
'vms': filter(lambda v: not v.editor_elements.exists(),
connections['vms']),
'vxlans': filter(lambda v: not v.editor_elements.exists(),
connections['vxlans']),
}
def _get_connections(self):
""" Returns connections and theirs participants. """
vms = Instance.get_objects_with_level('user', self.request.user)
connections = []
vm_set = set()
vxlan_set = set()
for vm in vms:
for intf in vm.interface_set.filter(vxlan__isnull=False):
vm_set.add(vm)
vxlan_set.add(intf.vxlan)
connections.append({
'source': vm,
'target': intf.vxlan,
})
return {
'connections': connections,
'vms': vm_set,
'vxlans': vxlan_set,
}
def is_router_enabled(self):
# TODO
return True
def add_resource_url(self, view, resources):
pass #TODO
# tenant_id = self.request.user.tenant_id
# for resource in resources:
# if (resource.get('tenant_id')
# and tenant_id != resource.get('tenant_id')):
# continue
# resource['url'] = reverse(view, None, [str(resource['id'])])
def _check_router_external_port(self, ports, router_id, network_id):
for port in ports:
if (port['network_id'] == network_id
and port['device_id'] == router_id):
return True
return False
def _get_networks(self, request):
# Get neutron data
# if we didn't specify tenant_id, all networks shown as admin user.
# so it is need to specify the networks. However there is no need to
# specify tenant_id for subnet. The subnet which belongs to the public
# network is needed to draw subnet information on public network.
try:
neutron_networks = openstack_api.neutron.network_list_for_tenant(
request,
request.user.tenant_id)
except Exception:
neutron_networks = []
networks = []
for network in neutron_networks:
obj = {'name': network.name_or_id,
'id': network.id,
'subnets': [{'id': subnet.id,
'cidr': subnet.cidr}
for subnet in network.subnets],
'status': network.status, #TODO
'original_status': network.status,
'router:external': network['router:external']}
self.add_resource_url('horizon:project:networks:subnets:detail',
obj['subnets'])
networks.append(obj)
return networks
def _get_servers(self, request):
console_invalid_status = {
'shutoff', 'suspended', 'resize', 'verify_resize',
'revert_resize', 'migrating', 'build', 'shelved',
'shelved_offloaded'}
# Get nova data
try:
servers, more = openstack_api.nova.server_list(request)
except Exception:
servers = []
data = []
console_type = "VNC"
# lowercase of the keys will be used at the end of the console URL.
for server in servers:
server_data = {'name': server.name,
'status': server.status, #TODO
'original_status': server.status,
'task': getattr(server, 'OS-EXT-STS:task_state'),
'id': server.id}
# Avoid doing extra calls for console if the server is in
# a invalid status for console connection
if server.status.lower() not in console_invalid_status:
if console_type:
server_data['console'] = 'auto_console'
data.append(server_data)
self.add_resource_url('horizon:project:instances:detail', data)
return data
def _serialize_elements(self, elements):
return (map(self._vm_serializer, elements['vms']) +
map(self._vxlan_serializer, elements['vxlans']))
def _get_modifiable_object(self, model, connection,
attr_name, filter_attr):
value = connection.get(attr_name)
if value is not None:
value = model.get_objects_with_level(
'user', self.request.user).filter(
**{filter_attr: value}).first()
return value
def _element_list_operation(self, node_list, operation):
for e in node_list:
elem = dict(e)
type = elem.pop('type')
id = elem.pop('id')
model = Instance if type == 'vm' else Vxlan
filter = {'pk': id} if type == 'vm' else {'vni': id}
object = model.get_objects_with_level(
'user', self.request.user).get(**filter)
operation(object.editor_elements, elem)
def _update_element(self, elements, elem):
elements.update_or_create(owner=self.request.user,
defaults=elem)
def _remove_element(self, elements, elem):
elements.filter(owner=self.request.user).delete()
def _interface_list_operation(self, if_list, operation):
for con in if_list:
vm = self._get_modifiable_object(Instance, con, 'source', 'pk')
vxlan = self._get_modifiable_object(Vxlan, con, 'target', 'vni')
if vm and vxlan:
operation(vm, vxlan)
def _add_interface(self, vm, vxlan):
vm.add_user_interface(
user=self.request.user, vxlan=vxlan, system=vm.system)
def _remove_interface(self, vm, vxlan):
intf = vm.interface_set.filter(vxlan=vxlan).first()
if intf:
vm.remove_user_interface(
interface=intf, user=self.request.user, system=vm.system)
def _get_ports(self, request, networks):
try:
neutron_ports = openstack_api.neutron.port_list(request)
except Exception:
neutron_ports = []
# we should filter out ports connected to non tenant networks
# which they have no visibility to
tenant_network_ids = [network['id'] for network in networks]
ports = [{'id': port.id,
'network_id': port.network_id,
'device_id': port.device_id,
'fixed_ips': port.fixed_ips,
'device_owner': port.device_owner,
'status': port.status, #TODO
'original_status': port.status}
for port in neutron_ports
if port.device_owner != 'network:router_ha_interface'
and port.network_id in tenant_network_ids]
self.add_resource_url('horizon:project:networks:ports:detail',
ports)
return ports
def _prepare_gateway_ports(self, routers, ports):
# user can't see port on external network. so we are
# adding fake port based on router information
for router in routers:
external_gateway_info = router.get('external_gateway_info')
if not external_gateway_info:
continue
external_network = external_gateway_info.get(
'network_id')
if not external_network:
continue
if self._check_router_external_port(ports,
router['id'],
external_network):
continue
fake_port = {'id': 'gateway%s' % external_network,
'network_id': external_network,
'device_id': router['id'],
'fixed_ips': []}
ports.append(fake_port)
def _get_routers(self, request):
if not self.is_router_enabled:
return []
try:
neutron_routers = openstack_api.neutron.router_list(
request,
tenant_id=request.user.tenant_id)
except Exception:
neutron_routers = []
routers = [{'id': router.id,
'name': router.name_or_id,
'status': router.status, #TODO
'original_status': router.status,
'external_gateway_info': router.external_gateway_info}
for router in neutron_routers]
self.add_resource_url('horizon:project:routers:detail', routers)
return routers
def get(self, request, *args, **kwargs):
networks = self._get_networks(request)
data = {'servers': self._get_servers(request),
'networks': networks,
'ports': self._get_ports(request, networks),
'routers': self._get_routers(request)}
self._prepare_gateway_ports(data['routers'], data['ports'])
json_string = json.dumps(data, cls=LazyTranslationEncoder,
ensure_ascii=False)
return HttpResponse(json_string, content_type='text/json')
def remove_host_group(request, **kwargs):
host = Host.objects.get(pk=kwargs['pk'])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment