Created mCord service page
diff --git a/xos/configurations/frontend/docker-compose.yml b/xos/configurations/frontend/docker-compose.yml
index c7c9c19..9c4680a 100644
--- a/xos/configurations/frontend/docker-compose.yml
+++ b/xos/configurations/frontend/docker-compose.yml
@@ -24,3 +24,5 @@
- ../../core/static:/opt/xos/core/static
- ../../templates/admin:/opt/xos/templates/admin
- ../../configurations:/opt/xos/configurations
+ - ../../xos:/opt/xos/xos
+ - ../../core/views:/opt/xos/core/views
diff --git a/xos/configurations/frontend/mocks/mcord.yaml b/xos/configurations/frontend/mocks/mcord.yaml
index 2c6648b..c738a49 100644
--- a/xos/configurations/frontend/mocks/mcord.yaml
+++ b/xos/configurations/frontend/mocks/mcord.yaml
@@ -8,7 +8,52 @@
topology_template:
node_templates:
# M-CORD Services
+
+ # RAN
+ vBBU:
+ type: tosca.nodes.Service
+ properties:
+ view_url: /static/mCordServices/vBBU.html
+ kind: RAN
+ # EPC
+ vMME:
+ type: tosca.nodes.Service
+ properties:
+ view_url: /static/mCordServices/vMME.html
+ kind: EPC
+
+ vSGW:
+ type: tosca.nodes.Service
+ properties:
+ view_url: /static/mCordServices/vSGW.html
+ kind: EPC
+
+ vPGW:
+ type: tosca.nodes.Service
+ properties:
+ view_url: /static/mCordServices/vPGW.html
+ kind: EPC
+
+ # EDGE
+ Cache:
+ type: tosca.nodes.Service
+ properties:
+ view_url: /static/mCordServices/cache.html
+ kind: EDGE
+
+ Firewall:
+ type: tosca.nodes.Service
+ properties:
+ view_url: /static/mCordServices/firewall.html
+ kind: EDGE
+
+ Video Optimization:
+ type: tosca.nodes.Service
+ properties:
+ view_url: /mcord/video
+ kind: EDGE
+
# Images
trusty-server-multi-nic:
type: tosca.nodes.Image
@@ -245,6 +290,11 @@
properties:
url: template:xosMcordTopology
+ Ceilometer:
+ type: tosca.nodes.DashboardView
+ properties:
+ url: template:xosCeilometerDashboard
+
padmin@vicci.org:
type: tosca.nodes.User
properties:
@@ -255,3 +305,6 @@
- mcord_dashboard:
node: Topology
relationship: tosca.relationships.UsesDashboard
+ - ceilometer_dashboard:
+ node: Ceilometer
+ relationship: tosca.relationships.UsesDashboard
diff --git a/xos/configurations/frontend/mocks/xos_mcord_config b/xos/configurations/frontend/mocks/xos_mcord_config
index f0611e0..7730f3b 100644
--- a/xos/configurations/frontend/mocks/xos_mcord_config
+++ b/xos/configurations/frontend/mocks/xos_mcord_config
@@ -1,6 +1,6 @@
[gui]
branding_name=M-CORD
-#branding_css=/static/cord.css
branding_icon=/static/cord-logo.png
branding_favicon=/static/cord-favicon.png
branding_bg=/static/mcord-bg2.jpg
+service_view_class=core.views.mCordServiceGrid.ServiceGridView
diff --git a/xos/core/static/mCordServices/vMME.html b/xos/core/static/mCordServices/vMME.html
new file mode 100644
index 0000000..879f70b
--- /dev/null
+++ b/xos/core/static/mCordServices/vMME.html
@@ -0,0 +1,755 @@
+<form enctype="multipart/form-data" action="" method="post" id="ceilometerservice_form" class="form-horizontal" novalidate="">
+ <input type="hidden" name="csrfmiddlewaretoken" value="B9gutUN7l65x3BBXOtAirdnXxRg7v9ZH">
+ <div class="tab-content tab-content-main">
+
+
+
+
+
+
+
+
+ <div class="suit-include suit-tab suit-tab-administration hide"><div class="left-nav">
+<ul>
+<li><a href="/admin/ceilometer/monitoringchannel/">Monitoring Channels</a></li>
+</ul>
+</div>
+
+</div>
+
+
+
+
+
+
+
+<fieldset class="module aligned suit-tab suit-tab-general show">
+
+
+ <div class="panel fieldset-body">
+
+
+
+
+ <div class="form-group field-backend_status_text ">
+
+
+ <label class="control-label col-xs-12 col-sm-2"><label>Backend status text:</label></label>
+
+ <div class="form-column col-xs-12 col-sm-8 col-md-6 col-lg-4">
+
+
+
+ <p><img src="/static/admin/img/icon_clock.gif"> Pending sync, last_status = 0 - Provisioning in progress</p>
+
+
+
+
+
+
+
+ </div>
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+ <div class="form-group field-name ">
+
+
+ <label class="control-label col-xs-12 col-sm-2"><label class="required" for="id_name">Name:</label></label>
+
+ <div class="form-column widget-AdminTextInputWidget col-xs-12 col-sm-8 col-md-6 col-lg-4">
+
+
+
+ <input class="vTextField form-control" id="id_name" maxlength="30" name="name" type="text" value="service_ceilometer">
+
+
+
+
+
+
+ <div class="help-block">Service Name</div>
+
+
+ </div>
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+ <div class="form-group field-enabled ">
+
+
+ <label class="control-label col-xs-12 col-sm-2"><label class="vCheckboxLabel" for="id_enabled">Enabled</label></label>
+
+ <div class="form-column widget-CheckboxInput col-xs-12 col-sm-8 col-md-6 col-lg-4">
+
+
+
+ <input checked="checked" id="id_enabled" name="enabled" type="checkbox">
+
+
+
+
+
+
+
+ </div>
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+ <div class="form-group field-versionNumber ">
+
+
+ <label class="control-label col-xs-12 col-sm-2"><label class="required" for="id_versionNumber">VersionNumber:</label></label>
+
+ <div class="form-column widget-AdminTextInputWidget col-xs-12 col-sm-8 col-md-6 col-lg-4">
+
+
+
+ <input class="vTextField form-control" id="id_versionNumber" maxlength="30" name="versionNumber" type="text">
+
+
+
+
+
+
+ <div class="help-block">Version of Service Definition</div>
+
+
+ </div>
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+ <div class="form-group field-description ">
+
+
+ <label class="control-label col-xs-12 col-sm-2"><label for="id_description">Description:</label></label>
+
+ <div class="form-column widget-AdminTextareaWidget col-xs-12 col-sm-8 col-md-6 col-lg-4">
+
+
+
+ <textarea class="vLargeTextField form-control" cols="40" id="id_description" maxlength="254" name="description" rows="10"></textarea>
+
+
+
+
+
+
+ <div class="help-block">Description of Service</div>
+
+
+ </div>
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+ <div class="form-group field-ceilometer_pub_sub_url ">
+
+
+ <label class="control-label col-xs-12 col-sm-2"><label for="id_ceilometer_pub_sub_url">Ceilometer pub sub url:</label></label>
+
+ <div class="form-column widget-TextInput col-xs-12 col-sm-8 col-md-6 col-lg-4">
+
+
+
+ <input class="form-control" id="id_ceilometer_pub_sub_url" maxlength="1024" name="ceilometer_pub_sub_url" type="text" value="http://10.11.10.1:4455/">
+
+
+
+
+
+
+ <div class="help-block">REST URL of ceilometer PUB/SUB component in http://IP:port/ format</div>
+
+
+ </div>
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+ <div class="form-group field-view_url ">
+
+
+ <label class="control-label col-xs-12 col-sm-2"><label for="id_view_url">View url:</label></label>
+
+ <div class="form-column widget-AdminTextInputWidget col-xs-12 col-sm-8 col-md-6 col-lg-4">
+
+
+
+ <input class="vTextField form-control" id="id_view_url" maxlength="1024" name="view_url" type="text" value="/admin/ceilometer/ceilometerservice/$id$/">
+
+
+
+
+
+
+
+ </div>
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+ <div class="form-group field-icon_url ">
+
+
+ <label class="control-label col-xs-12 col-sm-2"><label for="id_icon_url">Icon url:</label></label>
+
+ <div class="form-column widget-AdminTextInputWidget col-xs-12 col-sm-8 col-md-6 col-lg-4">
+
+
+
+ <input class="vTextField form-control" id="id_icon_url" maxlength="1024" name="icon_url" type="text">
+
+
+
+
+
+
+
+ </div>
+
+
+ </div>
+
+
+
+
+
+
+
+ </div>
+
+</fieldset>
+
+
+
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="inline-group suit-tab suit-tab-slices hide" id="slices-group">
+ <div class="tabular inline-related ">
+<input id="id_slices-TOTAL_FORMS" name="slices-TOTAL_FORMS" type="hidden" value="1" autocomplete="off"><input id="id_slices-INITIAL_FORMS" name="slices-INITIAL_FORMS" type="hidden" value="1"><input id="id_slices-MIN_NUM_FORMS" name="slices-MIN_NUM_FORMS" type="hidden" value="0"><input id="id_slices-MAX_NUM_FORMS" name="slices-MAX_NUM_FORMS" type="hidden" value="1000" autocomplete="off">
+<fieldset class="module">
+ <h2>Slices</h2>
+
+ <div class="panel-border">
+ <table class="table table-striped table-bordered table-hover table-condensed table-primary">
+ <thead><tr>
+
+
+ <th colspan="1">
+
+ </th>
+
+
+
+ <th class="required">Name
+ <img src="/static/admin/img/icon-unknown.gif" class="help help-tooltip" width="10" height="10" alt="(The Name of the Slice)" title="The Name of the Slice">
+ </th>
+
+
+
+ <th class="required">Site
+ <img src="/static/admin/img/icon-unknown.gif" class="help help-tooltip" width="10" height="10" alt="(The Site this Slice belongs to)" title="The Site this Slice belongs to">
+ </th>
+
+
+
+ <th class="required">ServiceClass
+
+ </th>
+
+
+
+ <th>Details
+
+ </th>
+
+
+ <th>Delete?</th>
+ </tr></thead>
+
+ <tbody>
+
+
+ <tr class="form-row row1 has_original dynamic-slices" id="slices-0">
+ <td class="original">
+
+ <input id="id_slices-0-id" name="slices-0-id" type="hidden" value="1">
+ <input id="id_slices-0-service" name="slices-0-service" type="hidden" value="1">
+
+ </td>
+
+
+
+
+ <td class="field-backend_status_icon">
+
+ <p><br> <script type="text/javascript">$(document).ready(function () {$("#show_details_1").click(function () {$("#status1").dialog({modal: true, height: 200, width: 200 });});});</script><br> <br> </p><div style="display:none;" id="status1" title="Details"><br> <p>Backoff Exponent: 0</p><br> <p>Last Success: '2016-02-27 14:09'</p><br> <p>Failures: None</p><br> <p>Last Failure: None</p><br> </div><br> <span style="min-width:16px;" title="successfully enacted"><a id="show_details_1" href="#"><img src="/static/admin/img/icon_success.gif"></a></span><p></p>
+
+ </td>
+
+
+
+
+
+ <td class="field-name">
+
+
+ <input class="vTextField form-control" id="id_slices-0-name" maxlength="80" name="slices-0-name" type="text" value="mysite_ceilometer">
+
+ </td>
+
+
+
+
+
+ <td class="field-site">
+
+
+ <div class="input-group"><select class="form-control" id="id_slices-0-site" name="slices-0-site">
+<option value="">---------</option>
+<option value="1" selected="selected">mysite</option>
+</select><span class="input-group-btn"><a href="/admin/core/site/add/?_to_field=id" class="add-another btn btn-default" id="add_id_slices-0-site" onclick="return showAddAnotherPopup(this);" title="Add Another"><span class="glyphicon glyphicon-plus-sign color-success"></span></a></span></div>
+
+ </td>
+
+
+
+
+
+ <td class="field-serviceClass">
+
+
+ <div class="input-group"><select class="form-control" id="id_slices-0-serviceClass" name="slices-0-serviceClass">
+<option value="1" selected="selected">Best Effort</option>
+</select><span class="input-group-btn"><a href="/admin/core/serviceclass/add/?_to_field=id" class="add-another btn btn-default" id="add_id_slices-0-serviceClass" onclick="return showAddAnotherPopup(this);" title="Add Another"><span class="glyphicon glyphicon-plus-sign color-success"></span></a></span></div><input id="initial-slices-0-id_slices-0-serviceClass" name="initial-slices-0-serviceClass" type="hidden" value="1">
+
+ </td>
+
+
+
+
+
+ <td class="field-selflink">
+
+ <p><a href="/admin/core/slice/1/">Details</a></p>
+
+ </td>
+
+
+
+
+
+ <td class="delete"><input id="id_slices-0-DELETE" name="slices-0-DELETE" type="checkbox"></td>
+
+ </tr>
+
+
+ <tr class="form-row row2 empty-form" id="slices-empty">
+ <td class="original">
+
+ <input id="id_slices-__prefix__-id" name="slices-__prefix__-id" type="hidden">
+ <input id="id_slices-__prefix__-service" name="slices-__prefix__-service" type="hidden" value="1">
+
+ </td>
+
+
+
+
+ <td class="field-backend_status_icon">
+
+ <p> <span style="min-width:16px;" title="Pending sync, last_status = 0 - Provisioning in progress"><img src="/static/admin/img/icon_clock.gif"></span></p>
+
+ </td>
+
+
+
+
+
+ <td class="field-name">
+
+
+ <input class="vTextField form-control" id="id_slices-__prefix__-name" maxlength="80" name="slices-__prefix__-name" type="text">
+
+ </td>
+
+
+
+
+
+ <td class="field-site">
+
+
+ <div class="input-group"><select class="form-control" id="id_slices-__prefix__-site" name="slices-__prefix__-site">
+<option value="" selected="selected">---------</option>
+<option value="1">mysite</option>
+</select><span class="input-group-btn"><a href="/admin/core/site/add/?_to_field=id" class="add-another btn btn-default" id="add_id_slices-__prefix__-site" onclick="return showAddAnotherPopup(this);" title="Add Another"><span class="glyphicon glyphicon-plus-sign color-success"></span></a></span></div>
+
+ </td>
+
+
+
+
+
+ <td class="field-serviceClass">
+
+
+ <div class="input-group"><select class="form-control" id="id_slices-__prefix__-serviceClass" name="slices-__prefix__-serviceClass">
+<option value="1" selected="selected">Best Effort</option>
+</select><span class="input-group-btn"><a href="/admin/core/serviceclass/add/?_to_field=id" class="add-another btn btn-default" id="add_id_slices-__prefix__-serviceClass" onclick="return showAddAnotherPopup(this);" title="Add Another"><span class="glyphicon glyphicon-plus-sign color-success"></span></a></span></div><input id="initial-slices-__prefix__-id_slices-__prefix__-serviceClass" name="initial-slices-__prefix__-serviceClass" type="hidden" value="1">
+
+ </td>
+
+
+
+
+
+ <td class="field-selflink">
+
+ <p>Not present</p>
+
+ </td>
+
+
+
+
+
+ <td class="delete"></td>
+
+ </tr>
+
+ <tr class="add-row"><td colspan="7"><a href="javascript:void(0)">Add another Slice</a></td></tr></tbody>
+ </table>
+ </div>
+</fieldset>
+ </div>
+</div>
+
+<script type="text/javascript">
+
+(function($) {
+ $("#slices-group .tabular.inline-related tbody tr").tabularFormset({
+ prefix: "slices",
+ adminStaticPrefix: '/static/admin/',
+ addText: "Add another Slice",
+ deleteText: "Remove"
+ });
+})(django.jQuery);
+</script>
+
+
+
+
+<div class="inline-group suit-tab suit-tab-serviceattrs hide" id="serviceattributes-group">
+ <div class="tabular inline-related ">
+<input id="id_serviceattributes-TOTAL_FORMS" name="serviceattributes-TOTAL_FORMS" type="hidden" value="0" autocomplete="off"><input id="id_serviceattributes-INITIAL_FORMS" name="serviceattributes-INITIAL_FORMS" type="hidden" value="0"><input id="id_serviceattributes-MIN_NUM_FORMS" name="serviceattributes-MIN_NUM_FORMS" type="hidden" value="0"><input id="id_serviceattributes-MAX_NUM_FORMS" name="serviceattributes-MAX_NUM_FORMS" type="hidden" value="1000" autocomplete="off">
+<fieldset class="module">
+ <h2>Service attributes</h2>
+
+ <div class="panel-border">
+ <table class="table table-striped table-bordered table-hover table-condensed table-primary">
+ <thead><tr>
+
+
+ <th colspan="1" class="required">Name
+ <img src="/static/admin/img/icon-unknown.gif" class="help help-tooltip" width="10" height="10" alt="(Attribute Name)" title="Attribute Name">
+ </th>
+
+
+
+ <th class="required">Value
+ <img src="/static/admin/img/icon-unknown.gif" class="help help-tooltip" width="10" height="10" alt="(Attribute Value)" title="Attribute Value">
+ </th>
+
+
+ <th>Delete?</th>
+ </tr></thead>
+
+ <tbody>
+
+
+ <tr class="form-row row1 empty-form" id="serviceattributes-empty">
+ <td class="original">
+
+ <input id="id_serviceattributes-__prefix__-id" name="serviceattributes-__prefix__-id" type="hidden">
+ <input id="id_serviceattributes-__prefix__-service" name="serviceattributes-__prefix__-service" type="hidden" value="1">
+
+ </td>
+
+
+
+
+ <td class="field-name">
+
+
+ <input class="vTextField form-control" id="id_serviceattributes-__prefix__-name" maxlength="128" name="serviceattributes-__prefix__-name" type="text">
+
+ </td>
+
+
+
+
+
+ <td class="field-value">
+
+
+ <input class="vTextField form-control" id="id_serviceattributes-__prefix__-value" maxlength="1024" name="serviceattributes-__prefix__-value" type="text">
+
+ </td>
+
+
+
+
+
+ <td class="delete"></td>
+
+ </tr>
+
+ <tr class="add-row"><td colspan="4"><a href="javascript:void(0)">Add another Service attribute</a></td></tr></tbody>
+ </table>
+ </div>
+</fieldset>
+ </div>
+</div>
+
+<script type="text/javascript">
+
+(function($) {
+ $("#serviceattributes-group .tabular.inline-related tbody tr").tabularFormset({
+ prefix: "serviceattributes",
+ adminStaticPrefix: '/static/admin/',
+ addText: "Add another Service attribute",
+ deleteText: "Remove"
+ });
+})(django.jQuery);
+</script>
+
+
+
+
+<div class="inline-group suit-tab suit-tab-serviceprivileges hide" id="serviceprivileges-group">
+ <div class="tabular inline-related last-related">
+<input id="id_serviceprivileges-TOTAL_FORMS" name="serviceprivileges-TOTAL_FORMS" type="hidden" value="0" autocomplete="off"><input id="id_serviceprivileges-INITIAL_FORMS" name="serviceprivileges-INITIAL_FORMS" type="hidden" value="0"><input id="id_serviceprivileges-MIN_NUM_FORMS" name="serviceprivileges-MIN_NUM_FORMS" type="hidden" value="0"><input id="id_serviceprivileges-MAX_NUM_FORMS" name="serviceprivileges-MAX_NUM_FORMS" type="hidden" value="1000" autocomplete="off">
+<fieldset class="module">
+ <h2>Service privileges</h2>
+
+ <div class="panel-border">
+ <table class="table table-striped table-bordered table-hover table-condensed table-primary">
+ <thead><tr>
+
+
+ <th colspan="1">
+
+ </th>
+
+
+
+ <th class="required">User
+
+ </th>
+
+
+
+ <th class="required">Role
+
+ </th>
+
+
+ <th>Delete?</th>
+ </tr></thead>
+
+ <tbody>
+
+
+ <tr class="form-row row1 empty-form" id="serviceprivileges-empty">
+ <td class="original">
+
+ <input id="id_serviceprivileges-__prefix__-id" name="serviceprivileges-__prefix__-id" type="hidden">
+ <input id="id_serviceprivileges-__prefix__-service" name="serviceprivileges-__prefix__-service" type="hidden" value="1">
+
+ </td>
+
+
+
+
+ <td class="field-backend_status_icon">
+
+ <p> <span style="min-width:16px;" title="Pending sync, last_status = 0 - Provisioning in progress"><img src="/static/admin/img/icon_clock.gif"></span></p>
+
+ </td>
+
+
+
+
+
+ <td class="field-user">
+
+
+ <div class="input-group"><select class="form-control" id="id_serviceprivileges-__prefix__-user" name="serviceprivileges-__prefix__-user">
+<option value="" selected="selected">---------</option>
+<option value="1">padmin@vicci.org</option>
+</select><span class="input-group-btn"><a href="/admin/core/user/add/?_to_field=id" class="add-another btn btn-default" id="add_id_serviceprivileges-__prefix__-user" onclick="return showAddAnotherPopup(this);" title="Add Another"><span class="glyphicon glyphicon-plus-sign color-success"></span></a></span></div>
+
+ </td>
+
+
+
+
+
+ <td class="field-role">
+
+
+ <div class="input-group"><select class="form-control" id="id_serviceprivileges-__prefix__-role" name="serviceprivileges-__prefix__-role">
+<option value="" selected="selected">---------</option>
+</select></div>
+
+ </td>
+
+
+
+
+
+ <td class="delete"></td>
+
+ </tr>
+
+ <tr class="add-row"><td colspan="5"><a href="javascript:void(0)">Add another Service privilege</a></td></tr></tbody>
+ </table>
+ </div>
+</fieldset>
+ </div>
+</div>
+
+<script type="text/javascript">
+
+(function($) {
+ $("#serviceprivileges-group .tabular.inline-related tbody tr").tabularFormset({
+ prefix: "serviceprivileges",
+ adminStaticPrefix: '/static/admin/',
+ addText: "Add another Service privilege",
+ deleteText: "Remove"
+ });
+})(django.jQuery);
+</script>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="form-buttons clearfix">
+ <button type="submit" class="btn btn-high btn-success" name="_save">Save</button>
+ <button type="submit" name="_continue" class=" btn btn-high btn-info">Save and continue editing</button>
+
+ <button type="submit" name="_addanother" class="btn btn-info">Save and add another</button>
+
+
+
+ <a href="delete/" class="text-error deletelink">Delete</a>
+
+
+</div>
+
+
+
+
+
+
+<script type="text/javascript">
+(function($) {
+ var field;
+
+
+})(django.jQuery);
+</script>
+
+
+
+ </form>
\ No newline at end of file
diff --git a/xos/core/static/xos.css b/xos/core/static/xos.css
index d00e625..8315b2b 100644
--- a/xos/core/static/xos.css
+++ b/xos/core/static/xos.css
@@ -82,10 +82,6 @@
min-height: 900px;
}
-.ui-tabs-panel {
- min-height: 700px;
-}
-
#wrapper.toggled #page-content-wrapper {
position: absolute;
margin-right: -250px;
@@ -335,6 +331,11 @@
border: 0px;
}
+.ui-tabs-panel {
+ min-height: 700px;
+ position: relative;
+}
+
.ui-tabs .ui-tabs-nav {
padding: 0 !important;
}
@@ -1384,12 +1385,25 @@
button.ui-dialog-titlebar-close:after {
content: "\e014";
}
-/* VCPe ADMIN FIX */
-/*form#vcpeservice_form ul li {
- display: inline-block;
- background: red;
- margin-top: 10px;
- width: auto;
- padding: 10px;
- border-radius: 5px;
+/* M-CORD SERVICE GRID */
+.m-cord .kind-container h2{
+ background-color: #337ab7;
+ padding: 10px;
+ color: #fff;
+ border-radius: 4px;
+ cursor: pointer;
}
+
+.m-cord .kind-container img.img-responsive {
+ display: inline-block;
+}
+
+.m-cord .kind-container .service-container{
+ height: 0px;
+ overflow: hidden;
+ transition: all .5s ease-in-out;
+}
+
+.m-cord .kind-container.active .service-container{
+ height: 162px
+}
\ No newline at end of file
diff --git a/xos/core/views/mCordServiceGrid.py b/xos/core/views/mCordServiceGrid.py
new file mode 100644
index 0000000..70a1c4a
--- /dev/null
+++ b/xos/core/views/mCordServiceGrid.py
@@ -0,0 +1,66 @@
+from django.http import HttpResponse
+from django.views.generic import TemplateView, View
+from django import template
+from django.shortcuts import render
+from core.models import *
+import json
+import os
+import time
+import tempfile
+
+
+class ServiceGridView(TemplateView):
+ head_template = r"""{% extends "admin/dashboard/dashboard_base.html" %}
+ {% load admin_static %}
+ {% block content %}
+ """
+
+ # I hate myself for doing this
+ script = """
+ <script type="text/javascript">
+ $(window).ready(function(){
+ $('.kind-container').on('click', function(){
+ $(this).toggleClass('active')
+ });
+ })
+ </script>
+ """
+
+ tail_template = r"{% endblock %}"
+
+ def get(self, request, name="root", *args, **kwargs):
+ head_template = self.head_template
+ tail_template = self.tail_template
+ html = self.script
+ html = html + '<div class="col-xs-12 m-cord">'
+
+ # Select the unique kind of services
+ for kind in Service.objects.values('kind').distinct():
+
+ html = html + '<div class="kind-container row">'
+ html = html + '<div class="col-xs-12"><h2>%s</h2></div>' % (kind["kind"])
+
+ # for each kind select services
+ for service in Service.objects.filter(kind=kind["kind"]):
+ image_url = service.icon_url
+ if (not image_url):
+ image_url = "/static/primarycons_blue/gear_2.png"
+ html = html + '<div class="col-xs-4 text-center service-container">'
+ html = html + '<a href="%s">' % (service.view_url)
+ html = html + '<img class="img-responsive" src="%s">' % (image_url)
+ html = html + "<h4>" + service.name + "</h4>"
+ html = html + '</a>'
+ html = html + "</div>"
+
+ html = html + "</div>"
+
+ html = html + "</div>"
+ t = template.Template(head_template + html + self.tail_template)
+
+ response_kwargs = {}
+ response_kwargs.setdefault('content_type', self.content_type)
+ return self.response_class(
+ request=request,
+ template=t,
+ **response_kwargs
+ )
diff --git a/xos/core/views/serviceGraph.py b/xos/core/views/serviceGraph.py
index 5ce0581..874d7a4 100644
--- a/xos/core/views/serviceGraph.py
+++ b/xos/core/views/serviceGraph.py
@@ -7,6 +7,7 @@
import time
import tempfile
+
class ServiceGridView(TemplateView):
head_template = r"""{% extends "admin/dashboard/dashboard_base.html" %}
{% load admin_static %}
@@ -21,7 +22,7 @@
html = '<table class="service-grid"><tr>'
- icons=[]
+ icons = []
for service in Service.objects.all():
view_url = service.view_url
if (not view_url):
@@ -32,27 +33,27 @@
if (not image_url):
image_url = "/static/primarycons_blue/gear_2.png"
- icons.append( {"name": service.name, "view_url": view_url, "image_url": image_url} )
+ icons.append({"name": service.name, "view_url": view_url, "image_url": image_url})
- icons.append( {"name": "Tenancy Graph", "view_url": "/serviceGraph.png", "image_url": "/static/primarycons_blue/service_graph.png", "horiz_rule": True} )
- icons.append( {"name": "Add Service", "view_url": "/admin/core/service/add/", "image_url": "/static/primarycons_blue/plus.png"} )
+ icons.append({"name": "Tenancy Graph", "view_url": "/serviceGraph.png", "image_url": "/static/primarycons_blue/service_graph.png", "horiz_rule": True})
+ icons.append({"name": "Add Service", "view_url": "/admin/core/service/add/", "image_url": "/static/primarycons_blue/plus.png"})
- i=0
+ i = 0
for icon in icons:
if icon.get("horiz_rule", False):
html = html + "</tr><tr><td colspan=4><hr></td></tr><tr>"
- i=0
+ i = 0
service_name = icon["name"]
view_url = icon["view_url"]
image_url = icon["image_url"]
- if (i%4) == 0:
+ if (i % 4) == 0:
html = html + '</tr><tr>'
html = html + '<td width=96 height=128 valign=top align=center><a class="service-grid-icon" href="%s"><img src="%s" height=64 width=64></img></a>' % (view_url, image_url)
html = html + '<p><a class="service-grid-icon-link" href="%s">%s</a></p></td>' % (view_url, service_name)
- i=i+1
+ i = i+1
html = html + '</tr></table>'
@@ -61,9 +62,11 @@
response_kwargs = {}
response_kwargs.setdefault('content_type', self.content_type)
return self.response_class(
- request = request,
- template = t,
- **response_kwargs)
+ request=request,
+ template=t,
+ **response_kwargs
+ )
+
class ServiceGraphViewOld(TemplateView):
# this attempt used networkx
@@ -78,14 +81,14 @@
import matplotlib.pyplot as plt
import nxedges
- plt.figure(figsize=(10,8))
+ plt.figure(figsize=(10, 8))
g = nx.DiGraph()
labels = {}
for service in Service.objects.all():
g.add_node(service.id)
- if len(service.name)>8:
+ if len(service.name) > 8:
labels[service.id] = service.name[:8] + "\n" + service.name[8:]
else:
labels[service.id] = service.name
@@ -96,13 +99,14 @@
g.add_edge(tenant.subscriber_service.id, tenant.provider_service.id)
pos = nx.graphviz_layout(g)
- nxedges.xos_draw_networkx_edges(g,pos,arrow_len=30)
- nx.draw_networkx_nodes(g,pos,node_size=5000)
- nx.draw_networkx_labels(g,pos,labels,font_size=12)
- #plt.axis('off')
+ nxedges.xos_draw_networkx_edges(g, pos, arrow_len=30)
+ nx.draw_networkx_nodes(g, pos, node_size=5000)
+ nx.draw_networkx_labels(g, pos, labels, font_size=12)
+ # plt.axis('off')
plt.savefig("/tmp/foo.png")
- return HttpResponse(open("/tmp/foo.png","r").read(), content_type="image/png")
+ return HttpResponse(open("/tmp/foo.png", "r").read(), content_type="image/png")
+
class ServiceGraphView(TemplateView):
# this attempt just uses graphviz directly
@@ -115,7 +119,7 @@
g = pgv.AGraph(directed=True)
g.graph_attr.update(size="8,4!")
g.graph_attr.update(dpi="100")
- #g.graph_attr.update(nodesep="2.5")
+ # g.graph_attr.update(nodesep="2.5")
g.graph_attr.update(overlap="false")
g.graph_attr.update(graphdir="TB")
@@ -123,8 +127,8 @@
provided_tenants = Tenant.objects.filter(provider_service=service, subscriber_service__isnull=False)
subscribed_tenants = Tenant.objects.filter(subscriber_service=service, provider_service__isnull=False)
if not (provided_tenants or subscribed_tenants):
- # nodes with no edges aren't interesting
- continue
+ # nodes with no edges aren't interesting
+ continue
g.add_node(service.id, label=service.name)
for tenant in Tenant.objects.all():
diff --git a/xos/services/__init__.py b/xos/services/__init__.py
index 8b13789..e69de29 100644
--- a/xos/services/__init__.py
+++ b/xos/services/__init__.py
@@ -1 +0,0 @@
-
diff --git a/xos/services/mcord/__init__.py b/xos/services/mcord/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/xos/services/mcord/__init__.py
diff --git a/xos/services/mcord/view.py b/xos/services/mcord/view.py
new file mode 100755
index 0000000..c2963be
--- /dev/null
+++ b/xos/services/mcord/view.py
@@ -0,0 +1,57 @@
+from django.http import HttpResponse
+from django.views.generic import TemplateView, View
+from django import template
+from core.models import *
+import json
+import os
+import time
+import tempfile
+
+
+class MCordView(TemplateView):
+ head_template = r"""{% extends "admin/dashboard/dashboard_base.html" %}
+ {% load admin_static %}
+ {% block content %}
+ """
+
+ tail_template = r"{% endblock %}"
+
+ def get(self, request, name="root", *args, **kwargs):
+ head_template = self.head_template
+ tail_template = self.tail_template
+
+ try:
+ hello_name = request.GET['hello_name']
+ world_name = request.GET['world_name']
+ instance_id_str = request.GET['instance_id']
+ instance_id = int(instance_id_str)
+
+ i = Instance.objects.get(pk=instance_id)
+ i.pk=None
+ i.userData=None
+ i.instance_id=None
+ i.instance_name=None
+ i.enacted=None
+ i.save()
+ h = Hello(name=hello_name,instance_backref=i)
+ h.save()
+ w = World(hello=h,name=world_name)
+ w.save()
+
+ t = template.Template(head_template + 'Done. New instance id: %r'%i.pk + self.tail_template)
+ except KeyError:
+ html = """<form>
+ Hello string: <input type="text" name="hello_name" placeholder="Planet"><br>
+ World string: <input type="text" name="world_name" placeholder="Earth"><br>
+ Id of instance to copy: <input type="text" name="instance_id" placeholder="3"><br>
+ <input type="submit" value="Submit">
+ </form>"""
+
+ t = template.Template(head_template + html + self.tail_template)
+
+ response_kwargs = {}
+ response_kwargs.setdefault('content_type', self.content_type)
+ return self.response_class(
+ request = request,
+ template = t,
+ **response_kwargs)
diff --git a/xos/xos/settings.py b/xos/xos/settings.py
index c8b0b07..04b54aa 100644
--- a/xos/xos/settings.py
+++ b/xos/xos/settings.py
@@ -9,6 +9,7 @@
from config import set_override
config = Config()
+
# Override the config from the environment. This is used leverage the LINK
# capability of docker. It would be far better to use DNS and that can be
# done in environments like kubernetes. Look for environment variables that
@@ -20,7 +21,7 @@
config.db_port = parsed.port
env_to_config_dict = {
- "XOS_DB_PORT" : overrideDbSettings
+ "XOS_DB_PORT": overrideDbSettings
}
for key, ofunc in env_to_config_dict.items():
@@ -30,21 +31,21 @@
GEOIP_PATH = "/usr/share/GeoIP"
XOS_DIR = "/opt/xos"
-DEBUG = False
+DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email@example.com'),
)
-#LOGIN_REDIRECT_URL = '/admin/core/user'
+# LOGIN_REDIRECT_URL = '/admin/core/user'
LOGIN_REDIRECT_URL = '/admin/loggedin/'
MANAGERS = ADMINS
DATABASES = {
'default': {
- 'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+ 'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': config.db_name, # Or path to database file if using sqlite3.
# The following settings are not used with sqlite3:
'USER': config.db_user,
@@ -160,7 +161,7 @@
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
-# 'django.contrib.sites',
+ # 'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
@@ -184,7 +185,7 @@
'rest_framework_swagger',
)
-if DJANGO_VERSION[1]>=7:
+if DJANGO_VERSION[1] >= 7:
# if django >= 1.7, then change the admin module
INSTALLED_APPS = list(INSTALLED_APPS)
INSTALLED_APPS[INSTALLED_APPS.index('django.contrib.admin')] = 'django.contrib.admin.apps.SimpleAdminConfig'
diff --git a/xos/xos/urls.py b/xos/xos/urls.py
index 4c3f07d..65af931 100644
--- a/xos/xos/urls.py
+++ b/xos/xos/urls.py
@@ -1,3 +1,4 @@
+import importlib
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
@@ -10,26 +11,57 @@
from core.views.legacyapi import LegacyXMLRPC
from core.views.serviceGraph import ServiceGridView, ServiceGraphView
from services.helloworld.view import *
-#from core.views.analytics import AnalyticsAjaxView
+from services.helloworld.view import *
+# from core.views.analytics import AnalyticsAjaxView
from core.models import *
from rest_framework import generics
from core.dashboard.sites import SitePlus
from django.http import HttpResponseRedirect
-#from core.xoslib import XOSLibDataView
+# from core.xoslib import XOSLibDataView
+
+# Django settings for XOS.
+from config import Config
+from config import set_override
+config = Config()
+
+
+def load_class(full_class_string):
+ """
+ dynamically load a class from a string
+ """
+
+ class_data = full_class_string.split(".")
+ module_path = ".".join(class_data[:-1])
+ class_str = class_data[-1]
+
+ module = importlib.import_module(module_path)
+ # Finally, we retrieve the Class
+ return getattr(module, class_str)
+
+servicePage = getattr(config, "gui_service_view_class", ServiceGridView)
+
+if(isinstance(servicePage, basestring)):
+ serviceClass = getattr(load_class(servicePage), "as_view")
+else:
+ serviceClass = getattr(servicePage, "as_view")
admin.site = SitePlus()
admin.autodiscover()
-def redirect_to_apache(request):
- """ bounce a request back to the apache server that is running on the machine """
- apache_url = "http://%s%s" % (request.META['HOSTNAME'], request.path)
- return HttpResponseRedirect(apache_url)
-urlpatterns = patterns('',
- # Examples:
+def redirect_to_apache(request):
+ """ bounce a request back to the apache server that is running on the machine """
+ apache_url = "http://%s%s" % (request.META['HOSTNAME'], request.path)
+ return HttpResponseRedirect(apache_url)
+
+urlpatterns = patterns(
+ '',
url(r'^observer', 'core.views.observer.Observer', name='observer'),
url(r'^helloworld', HelloWorldView.as_view(), name='helloWorld'),
- url(r'^serviceGrid', ServiceGridView.as_view(), name='serviceGrid'),
+
+ # url(r'^mcord', MCordView.as_view(), name='mcord'),
+
+ url(r'^serviceGrid', serviceClass(), name='serviceGrid'),
url(r'^serviceGraph.png', ServiceGraphView.as_view(), name='serviceGraph'),
url(r'^hpcConfig', 'core.views.hpc_config.HpcConfig', name='hpcConfig'),
@@ -41,20 +73,19 @@
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
url(r'^', include(admin.site.urls)),
- #url(r'^profile/home', 'core.views.home'),
+ # url(r'^profile/home', 'core.views.home'),
-# url(r'^admin/xoslib/(?P<name>\w+)/$', XOSLibDataView.as_view(), name="xoslib"),
+ # url(r'^admin/xoslib/(?P<name>\w+)/$', XOSLibDataView.as_view(), name="xoslib"),
url(r'^xmlrpc/legacyapi/$', 'core.views.legacyapi.LegacyXMLRPC', name='xmlrpc'),
-# url(r'^analytics/(?P<name>\w+)/$', AnalyticsAjaxView.as_view(), name="analytics"),
+ # url(r'^analytics/(?P<name>\w+)/$', AnalyticsAjaxView.as_view(), name="analytics"),
url(r'^files/', redirect_to_apache),
- #Adding in rest_framework urls
+ # Adding in rest_framework urls
url(r'^xos/', include('rest_framework.urls', namespace='rest_framework')),
# XOSLib rest methods
url(r'^xoslib/', include('core.xoslib.methods', namespace='xoslib')),
) + get_REST_patterns() + get_hpc_REST_patterns()
-