Merge "Sexy boxes drag and drop"
This commit is contained in:
		@@ -7,7 +7,7 @@ include AUTHORS
 | 
				
			|||||||
include LICENSE
 | 
					include LICENSE
 | 
				
			||||||
include Makefile
 | 
					include Makefile
 | 
				
			||||||
include manage.py
 | 
					include manage.py
 | 
				
			||||||
include README.md
 | 
					include README.rst
 | 
				
			||||||
include run_tests.sh
 | 
					include run_tests.sh
 | 
				
			||||||
include tox.ini
 | 
					include tox.ini
 | 
				
			||||||
include doc/Makefile
 | 
					include doc/Makefile
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,8 @@ from django.utils.translation import ugettext_lazy as _
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import horizon
 | 
					import horizon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from tuskar_ui.infrastructure import dashboard
 | 
					import tuskar_ui.infrastructure.dashboard as tuskar_dashboard
 | 
				
			||||||
 | 
					from tuskar_ui.infrastructure.overview.panel import Overview as TuskarOverview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Overview(horizon.Panel):
 | 
					class Overview(horizon.Panel):
 | 
				
			||||||
@@ -24,4 +25,5 @@ class Overview(horizon.Panel):
 | 
				
			|||||||
    slug = "overview"
 | 
					    slug = "overview"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dashboard.Infrastructure.register(Overview)
 | 
					tuskar_dashboard.Infrastructure.unregister(TuskarOverview)
 | 
				
			||||||
 | 
					tuskar_dashboard.Infrastructure.register(Overview)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
{% extends "horizon/common/_modal_form.html" %}
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block form_id %}provision_form{% endblock %}
 | 
					 | 
				
			||||||
{% block form_action %}{% url 'horizon:infrastructure:overview:deploy_confirmation' %}{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block modal_id %}provision_modal{% endblock %}
 | 
					 | 
				
			||||||
{% block modal-header %}{% trans "Deployment Confirmation" %}{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block modal-body %}
 | 
					 | 
				
			||||||
<div>
 | 
					 | 
				
			||||||
    <p>{% trans "You are about deploy your overcloud" %}
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    {% if autogenerated_parameters %}
 | 
					 | 
				
			||||||
        <strong>These parameters will be randomly generated before the deployment:</strong>
 | 
					 | 
				
			||||||
        <p>{{ autogenerated_parameters|join:", " }}</p>
 | 
					 | 
				
			||||||
    {% endif %}
 | 
					 | 
				
			||||||
    <p>{% trans "This operation cannot be undone. Are you sure you want to do that?" %}</p>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block modal-footer %}
 | 
					 | 
				
			||||||
  <input class="btn btn-primary" type="submit" value="{% trans "Deploy" %}" />
 | 
					 | 
				
			||||||
  <a href="{% url 'horizon:infrastructure:overview:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
{% extends "horizon/common/_modal_form.html" %}
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block form_id %}post_deploy_init_form{% endblock %}
 | 
					 | 
				
			||||||
{% block form_action %}{% url 'horizon:infrastructure:overview:post_deploy_init' %}{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block modal_id %}provision_modal{% endblock %}
 | 
					 | 
				
			||||||
{% block modal-header %}{% trans "Initialize Overcloud" %}{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block modal-body %}
 | 
					 | 
				
			||||||
<div>
 | 
					 | 
				
			||||||
  <fieldset>
 | 
					 | 
				
			||||||
    <div class="left">
 | 
					 | 
				
			||||||
      {% include "horizon/common/_form_fields.html" %}
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <div class="right">
 | 
					 | 
				
			||||||
      {% trans "Your OpenStack cloud nodes are deployed. They need to be initialized before your cloud will be live."%}
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </fieldset>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block modal-footer %}
 | 
					 | 
				
			||||||
  <input class="btn btn-primary" type="submit" value="{% trans "Initialize" %}" />
 | 
					 | 
				
			||||||
  <a href="{% url 'horizon:infrastructure:overview:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,25 +0,0 @@
 | 
				
			|||||||
{% extends "horizon/common/_modal_form.html" %}
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block form_id %}provision_form{% endblock %}
 | 
					 | 
				
			||||||
{% block form_action %}{% url 'horizon:infrastructure:overview:undeploy_confirmation' %}{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block modal_id %}provision_modal{% endblock %}
 | 
					 | 
				
			||||||
{% block modal-header %}{% trans "Undeployment Confirmation" %}{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block modal-body %}
 | 
					 | 
				
			||||||
<div>
 | 
					 | 
				
			||||||
    <p>{% trans "You are about undeploy your overcloud" %}
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
    <p>{% trans "This operation cannot be undone. Are you sure you want to do that?" %}</p>
 | 
					 | 
				
			||||||
  <fieldset>
 | 
					 | 
				
			||||||
  {% include "horizon/common/_form_fields.html" %}
 | 
					 | 
				
			||||||
  </fieldset>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block modal-footer %}
 | 
					 | 
				
			||||||
  <input class="btn btn-primary" type="submit" value="{% trans "Undeploy" %}" />
 | 
					 | 
				
			||||||
  <a href="{% url 'horizon:infrastructure:overview:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
{% extends 'infrastructure/base.html' %}
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% block title %}{% trans "Deploy overcloud" %}{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block page_header %}
 | 
					 | 
				
			||||||
  {% include "horizon/common/_page_header.html" with title=_("Deploy overcloud") %}
 | 
					 | 
				
			||||||
{% endblock page_header %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block infrastructure_main %}
 | 
					 | 
				
			||||||
    {% include "infrastructure/overview/_deploy_confirmation.html" %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,22 +0,0 @@
 | 
				
			|||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future%}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div class="deployment-icon">
 | 
					 | 
				
			||||||
  {% block deployment-icon %}
 | 
					 | 
				
			||||||
    <i class="fa fa-cloud text-info"></i>
 | 
					 | 
				
			||||||
  {% endblock %}
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
<div class="deployment-box clearfix">
 | 
					 | 
				
			||||||
  <h4>{% block deployment-title %}{% endblock %}</h4>
 | 
					 | 
				
			||||||
  {% block deployment-info %}{% endblock %}
 | 
					 | 
				
			||||||
  <div class="deployment-buttons clearfix">
 | 
					 | 
				
			||||||
    {% block deployment-buttons %}
 | 
					 | 
				
			||||||
      <a
 | 
					 | 
				
			||||||
    href="{% url 'horizon:infrastructure:overview:undeploy_confirmation' %}"
 | 
					 | 
				
			||||||
    class="btn btn-danger ajax-modal">
 | 
					 | 
				
			||||||
        <i class="fa fa-trash"></i>
 | 
					 | 
				
			||||||
        {% trans "Undeploy" %}
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    {% endblock %}
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
@@ -1,44 +0,0 @@
 | 
				
			|||||||
{% extends "infrastructure/overview/deployment_base.html" %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future%}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-icon %}
 | 
					 | 
				
			||||||
  <i class="fa fa-exclamation-circle text-danger"></i>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-title %}
 | 
					 | 
				
			||||||
            {% if stack.is_delete_failed %}
 | 
					 | 
				
			||||||
                {% trans "Undeploying failed" %}
 | 
					 | 
				
			||||||
            {% elif stack.is_failed %}
 | 
					 | 
				
			||||||
                {% trans "Deployment failed" %}
 | 
					 | 
				
			||||||
            {% else %}
 | 
					 | 
				
			||||||
                {% trans "Failure" %}
 | 
					 | 
				
			||||||
            {% endif %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-info %}
 | 
					 | 
				
			||||||
{% if last_failed_events %}
 | 
					 | 
				
			||||||
<strong>{% trans "Last failed events:" %}</strong>
 | 
					 | 
				
			||||||
{% for event in last_failed_events %}
 | 
					 | 
				
			||||||
<div>
 | 
					 | 
				
			||||||
  <dl>
 | 
					 | 
				
			||||||
    <dt>{% trans "Timestamp" %}</dt>
 | 
					 | 
				
			||||||
    <dd><time datetime="{{ event.event_time }}">{{ event.event_time }}</time></dd>
 | 
					 | 
				
			||||||
    <dt>{% trans "Resource Name" %}</dt>
 | 
					 | 
				
			||||||
    <dd>{{ event.resource_name }}</dd>
 | 
					 | 
				
			||||||
    <dt>{% trans "Status" %}</dt>
 | 
					 | 
				
			||||||
    <dd>{{ event.resource_status }}</dd>
 | 
					 | 
				
			||||||
    <dt>{% trans "Reason" %}</dt>
 | 
					 | 
				
			||||||
    <dd>{{ event.resource_status_reason }}</dd>
 | 
					 | 
				
			||||||
  </dl>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
{% endfor %}
 | 
					 | 
				
			||||||
{% endif %}
 | 
					 | 
				
			||||||
<p><a href="{% url 'horizon:infrastructure:history:index' %}">See full log</a></p>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-buttons %}
 | 
					 | 
				
			||||||
  {{ block.super }}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,23 +0,0 @@
 | 
				
			|||||||
{% extends "infrastructure/overview/deployment_base.html" %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future%}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-icon %}
 | 
					 | 
				
			||||||
  <i class="fa fa-exclamation-triangle text-warning"></i>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-title %}{% trans "Initialization" %}{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-info %}
 | 
					 | 
				
			||||||
<p>{% trans "Your OpenStack cloud is deployed but it needs to get initialized in order to get live." %}</p>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-buttons %}
 | 
					 | 
				
			||||||
  {{ block.super }}
 | 
					 | 
				
			||||||
  <a href="{% url 'horizon:infrastructure:overview:post_deploy_init' %}"
 | 
					 | 
				
			||||||
     class="btn btn-primary ajax-modal">
 | 
					 | 
				
			||||||
     <i class="fa fa-flag-checkered"></i>
 | 
					 | 
				
			||||||
     {% trans "Initialize" %}
 | 
					 | 
				
			||||||
  </a>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,33 +0,0 @@
 | 
				
			|||||||
{% extends "infrastructure/overview/deployment_base.html" %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future%}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-icon %}
 | 
					 | 
				
			||||||
  <i class="fa fa-check-circle-o text-success"></i>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
{% block deployment-title %}{% trans "Deployment is live" %}{% endblock %}
 | 
					 | 
				
			||||||
{% block deployment-info %}
 | 
					 | 
				
			||||||
<strong>{% trans "Access information" %}</strong>
 | 
					 | 
				
			||||||
<dl>
 | 
					 | 
				
			||||||
  {% for dashboard_url in dashboard_urls %}
 | 
					 | 
				
			||||||
  <dt>{% trans "Horizon URL" %}</dt>
 | 
					 | 
				
			||||||
  <dd><a href="{{ dashboard_url }}">{{ dashboard_url }}</a></dd>
 | 
					 | 
				
			||||||
  {% endfor %}
 | 
					 | 
				
			||||||
  <dt>{% trans "User name" %}</dt>
 | 
					 | 
				
			||||||
  <dd>admin</dd>
 | 
					 | 
				
			||||||
  <dt></dt>
 | 
					 | 
				
			||||||
  <dd>
 | 
					 | 
				
			||||||
    <form>
 | 
					 | 
				
			||||||
        <fieldset>
 | 
					 | 
				
			||||||
            <div class="form-group">
 | 
					 | 
				
			||||||
              <label class="control-label  required" for="id_password">{% trans "Password" %}</label>
 | 
					 | 
				
			||||||
              <div>
 | 
					 | 
				
			||||||
                <input class="form-control" id="id_password" type="password" value="{{ admin_password }}" disabled="true" readonly="true"/>
 | 
					 | 
				
			||||||
              </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </fieldset>
 | 
					 | 
				
			||||||
    </form>
 | 
					 | 
				
			||||||
  </dd>
 | 
					 | 
				
			||||||
</dl>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,43 +0,0 @@
 | 
				
			|||||||
{% extends "infrastructure/overview/deployment_base.html" %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future%}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-icon %}
 | 
					 | 
				
			||||||
{% if plan_invalid %}
 | 
					 | 
				
			||||||
  <i class="fa fa-exclamation-circle text-danger"></i>
 | 
					 | 
				
			||||||
{% else %}
 | 
					 | 
				
			||||||
  <i class="fa fa-check-circle text-success"></i>
 | 
					 | 
				
			||||||
{% endif %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-title %}
 | 
					 | 
				
			||||||
{% if plan_invalid %}
 | 
					 | 
				
			||||||
  {% trans "Design your deployment" %}
 | 
					 | 
				
			||||||
{% else %}
 | 
					 | 
				
			||||||
  {% trans "Ready to get deployed" %}
 | 
					 | 
				
			||||||
{% endif %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-info %}
 | 
					 | 
				
			||||||
<ul class="list-unstyled">
 | 
					 | 
				
			||||||
    {% for message in plan_messages %}
 | 
					 | 
				
			||||||
    <li class="{% if message.is_critical %}text-danger{% else %}text-warning{% endif %}"><p>
 | 
					 | 
				
			||||||
        {{ message.text }}
 | 
					 | 
				
			||||||
        {% if message.link_url %}
 | 
					 | 
				
			||||||
          <a href="{{ message.link_url }}">
 | 
					 | 
				
			||||||
            {{ message.link_label|default:message.link_url }}
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
        {% endif %}
 | 
					 | 
				
			||||||
    </p></li>
 | 
					 | 
				
			||||||
    {% endfor %}
 | 
					 | 
				
			||||||
</ul>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-buttons %}
 | 
					 | 
				
			||||||
<a href="{% url 'horizon:infrastructure:overview:deploy_confirmation' %}"
 | 
					 | 
				
			||||||
class="btn btn-primary ajax-modal btn-default {% if plan_invalid %}disabled{% endif %}">
 | 
					 | 
				
			||||||
<i class="fa fa-rocket"></i>
 | 
					 | 
				
			||||||
{% trans "Deploy" %}
 | 
					 | 
				
			||||||
</a>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,61 +0,0 @@
 | 
				
			|||||||
{% extends "infrastructure/overview/deployment_base.html" %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future%}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-icon %}
 | 
					 | 
				
			||||||
  <i class="fa fa-spinner text-info"></i>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-title %}
 | 
					 | 
				
			||||||
            {% if stack.is_deleting %}
 | 
					 | 
				
			||||||
                {% trans "Undeploying..." %}
 | 
					 | 
				
			||||||
            {% elif stack.is_deploying %}
 | 
					 | 
				
			||||||
                {% trans "Deploying..." %}
 | 
					 | 
				
			||||||
            {% endif %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-info %}
 | 
					 | 
				
			||||||
{% if progress %}
 | 
					 | 
				
			||||||
  <div class="progress">
 | 
					 | 
				
			||||||
    <div
 | 
					 | 
				
			||||||
      class="progress-bar progress-bar-striped active"
 | 
					 | 
				
			||||||
      role="progressbar"
 | 
					 | 
				
			||||||
      aria-valuenow="{{ progress }}"
 | 
					 | 
				
			||||||
      aria-valuemin="0"
 | 
					 | 
				
			||||||
      aria-valuemax="100"
 | 
					 | 
				
			||||||
      style="width: {{ progress }}%"
 | 
					 | 
				
			||||||
      ><span class="sr-only">{{ progress }}% {% trans "Complete" %}</span></div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
{% endif %}
 | 
					 | 
				
			||||||
{% if last_failed_events %}
 | 
					 | 
				
			||||||
  <strong>{% trans "Last failed events:" %}</strong>
 | 
					 | 
				
			||||||
{% for event in last_failed_events %}
 | 
					 | 
				
			||||||
<div>
 | 
					 | 
				
			||||||
  <dl>
 | 
					 | 
				
			||||||
    <dt>{% trans "Timestamp" %}</dt>
 | 
					 | 
				
			||||||
    <dd><time datetime="{{ event.event_time }}">{{ event.event_time }}</time></dd>
 | 
					 | 
				
			||||||
    <dt>{% trans "Resource Name" %}</dt>
 | 
					 | 
				
			||||||
    <dd>{{ event.resource_name }}</dd>
 | 
					 | 
				
			||||||
    <dt>{% trans "Status" %}</dt>
 | 
					 | 
				
			||||||
    <dd>{{ event.resource_status }}</dd>
 | 
					 | 
				
			||||||
    <dt>{% trans "Reason" %}</dt>
 | 
					 | 
				
			||||||
    <dd>{{ event.resource_status_reason }}</dd>
 | 
					 | 
				
			||||||
  </dl>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
{% endfor %}
 | 
					 | 
				
			||||||
{% endif %}
 | 
					 | 
				
			||||||
<p><a href="{% url 'horizon:infrastructure:history:index' %}">See full log</a></p>
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block deployment-buttons %}
 | 
					 | 
				
			||||||
    {% if stack.is_deploying %}
 | 
					 | 
				
			||||||
      <a
 | 
					 | 
				
			||||||
    href="{% url 'horizon:infrastructure:overview:undeploy_confirmation' %}"
 | 
					 | 
				
			||||||
    class="btn btn-danger ajax-modal">
 | 
					 | 
				
			||||||
        <i class="fa fa-close"></i>
 | 
					 | 
				
			||||||
        {% trans "Stop" %}
 | 
					 | 
				
			||||||
      </a>
 | 
					 | 
				
			||||||
    {% endif %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
{% extends 'infrastructure/base.html' %}
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% block title %}{% trans "Initialize" %}{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block page_header %}
 | 
					 | 
				
			||||||
  {% include "horizon/common/_page_header.html" with title=_("Initialize Overcloud") %}
 | 
					 | 
				
			||||||
{% endblock page_header %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block infrastructure_main %}
 | 
					 | 
				
			||||||
    {% include "infrastructure/overview/_post_deploy_init.html" %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -1,32 +0,0 @@
 | 
				
			|||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future %}
 | 
					 | 
				
			||||||
{% load form_helpers %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h4>{% trans "Deployment Roles" %}</h4>
 | 
					 | 
				
			||||||
<form method="POST" action="." class="deployment-roles-form">
 | 
					 | 
				
			||||||
{% csrf_token %}
 | 
					 | 
				
			||||||
{% include 'horizon/common/_form_errors.html' with form=form %}
 | 
					 | 
				
			||||||
{% for role in roles %}
 | 
					 | 
				
			||||||
    <div class="form-group well well-sm clearfix{% if field.errors %} error{% endif %} {{ field.css_classes }}">
 | 
					 | 
				
			||||||
      <div class="col-sm-2">
 | 
					 | 
				
			||||||
        {{ role.field|add_bootstrap_class }}
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      <div class="col-sm-10">
 | 
					 | 
				
			||||||
        <a
 | 
					 | 
				
			||||||
          href="{% url "horizon:infrastructure:roles:detail" role_id=role.id %}"
 | 
					 | 
				
			||||||
          class="deployment-roles-label"
 | 
					 | 
				
			||||||
        >{{ role.name }}</a>
 | 
					 | 
				
			||||||
        {% for error in role.field.errors %}
 | 
					 | 
				
			||||||
        <span class="help-block"><span class="text-danger">
 | 
					 | 
				
			||||||
          {{ error }}
 | 
					 | 
				
			||||||
        </span></span>
 | 
					 | 
				
			||||||
        {% endfor %}
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
{% endfor %}
 | 
					 | 
				
			||||||
<hr>
 | 
					 | 
				
			||||||
<button type="submit" class="btn btn-default">
 | 
					 | 
				
			||||||
  <i class="fa fa-save"></i>
 | 
					 | 
				
			||||||
  {% trans "Save changes" %}
 | 
					 | 
				
			||||||
</button>
 | 
					 | 
				
			||||||
</form>
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% load url from future %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<h4>{% trans "Deployment Roles" %}</h4>
 | 
					 | 
				
			||||||
{% for role in roles %}
 | 
					 | 
				
			||||||
    <div class="alert well-sm clearfix
 | 
					 | 
				
			||||||
      {% if role.error_node_count %}
 | 
					 | 
				
			||||||
        alert-danger
 | 
					 | 
				
			||||||
      {% elif role.deployed_node_count == role.planned_node_count %}
 | 
					 | 
				
			||||||
        alert-success
 | 
					 | 
				
			||||||
      {% else %}
 | 
					 | 
				
			||||||
        alert-info
 | 
					 | 
				
			||||||
      {% endif %}
 | 
					 | 
				
			||||||
      ">
 | 
					 | 
				
			||||||
      <div class="col-sm-2">
 | 
					 | 
				
			||||||
        {% if role.deployed_node_count < role.planned_node_count %}
 | 
					 | 
				
			||||||
          <strong>{{ role.deployed_node_count }}</strong><small class="text-muted">/{{ role.planned_node_count }}</small>
 | 
					 | 
				
			||||||
        {% else %}
 | 
					 | 
				
			||||||
          <strong>{{ role.planned_node_count }}</strong>
 | 
					 | 
				
			||||||
        {% endif %}
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      <div class="col-sm-10">
 | 
					 | 
				
			||||||
        <a
 | 
					 | 
				
			||||||
          href="{% url "horizon:infrastructure:roles:detail" role_id=role.id %}"
 | 
					 | 
				
			||||||
        >{{ role.name }}</a>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
{% endfor %}
 | 
					 | 
				
			||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
{% extends 'infrastructure/base.html' %}
 | 
					 | 
				
			||||||
{% load i18n %}
 | 
					 | 
				
			||||||
{% block title %}{% trans "Undeploy overcloud" %}{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block page_header %}
 | 
					 | 
				
			||||||
  {% include "horizon/common/_page_header.html" with title=_("Undeploy overcloud") %}
 | 
					 | 
				
			||||||
{% endblock page_header %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block infrastructure_main %}
 | 
					 | 
				
			||||||
    {% include "infrastructure/overview/_undeploy_confirmation.html" %}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
@@ -15,12 +15,14 @@
 | 
				
			|||||||
from django.conf import urls
 | 
					from django.conf import urls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from tuskar_ui.infrastructure.overview import views
 | 
					from tuskar_ui.infrastructure.overview import views
 | 
				
			||||||
import tuskar_boxes.views
 | 
					import tuskar_boxes.overview.views as boxes_views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
urlpatterns = urls.patterns(
 | 
					urlpatterns = urls.patterns(
 | 
				
			||||||
    '',
 | 
					    '',
 | 
				
			||||||
    urls.url(r'^$', tuskar_boxes.views.IndexView.as_view(), name='index'),
 | 
					    urls.url(r'^$',
 | 
				
			||||||
 | 
					             boxes_views.IndexView.as_view(),
 | 
				
			||||||
 | 
					             name='index'),
 | 
				
			||||||
    urls.url(r'^deploy-confirmation$',
 | 
					    urls.url(r'^deploy-confirmation$',
 | 
				
			||||||
             views.DeployConfirmationView.as_view(),
 | 
					             views.DeployConfirmationView.as_view(),
 | 
				
			||||||
             name='deploy_confirmation'),
 | 
					             name='deploy_confirmation'),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,40 @@
 | 
				
			|||||||
#    License for the specific language governing permissions and limitations
 | 
					#    License for the specific language governing permissions and limitations
 | 
				
			||||||
#    under the License.
 | 
					#    under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tuskar_ui import api
 | 
				
			||||||
from tuskar_ui.infrastructure.overview import views
 | 
					from tuskar_ui.infrastructure.overview import views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def flavor_nodes(request, flavor):
 | 
				
			||||||
 | 
					    """Lists all nodes that match the given flavor exactly."""
 | 
				
			||||||
 | 
					    for node in api.node.Node.list(request):
 | 
				
			||||||
 | 
					        if all([
 | 
				
			||||||
 | 
					            int(node.cpus) == int(flavor.vcpus),
 | 
				
			||||||
 | 
					            int(node.memory_mb) == int(flavor.ram),
 | 
				
			||||||
 | 
					            int(node.local_gb) == int(flavor.disk),
 | 
				
			||||||
 | 
					            # TODO(rdopieralski) add architecture when available
 | 
				
			||||||
 | 
					        ]):
 | 
				
			||||||
 | 
					            yield node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IndexView(views.IndexView):
 | 
					class IndexView(views.IndexView):
 | 
				
			||||||
    pass
 | 
					    template_name = "tuskar_boxes/overview/index.html"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_context_data(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        context = super(IndexView, self).get_context_data(*args, **kwargs)
 | 
				
			||||||
 | 
					        flavors = api.flavor.Flavor.list(self.request)
 | 
				
			||||||
 | 
					        flavors.sort(key=lambda np: (np.vcpus, np.ram, np.disk))
 | 
				
			||||||
 | 
					        context['flavors'] = []
 | 
				
			||||||
 | 
					        for flavor in flavors:
 | 
				
			||||||
 | 
					            nodes = [{
 | 
				
			||||||
 | 
					                'role': '',
 | 
				
			||||||
 | 
					            } for node in flavor_nodes(self.request, flavor)]
 | 
				
			||||||
 | 
					            flavor = {
 | 
				
			||||||
 | 
					                'name': flavor.name,
 | 
				
			||||||
 | 
					                'vcpus': flavor.vcpus,
 | 
				
			||||||
 | 
					                'ram': flavor.ram,
 | 
				
			||||||
 | 
					                'disk': flavor.disk,
 | 
				
			||||||
 | 
					                'nodes': nodes,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if nodes:  # Don't list empty flavors
 | 
				
			||||||
 | 
					                context['flavors'].append(flavor)
 | 
				
			||||||
 | 
					        return context
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,13 +4,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{% block title %}{% trans 'My OpenStack Deployment' %}{% endblock %}
 | 
					{% block title %}{% trans 'My OpenStack Deployment' %}{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block css %}
 | 
					 | 
				
			||||||
  {% if stack.is_deploying %}
 | 
					 | 
				
			||||||
    <meta http-equiv="refresh" content="30">
 | 
					 | 
				
			||||||
  {% endif %}
 | 
					 | 
				
			||||||
  {{ block.super }}
 | 
					 | 
				
			||||||
{% endblock %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{% block page_header %}
 | 
					{% block page_header %}
 | 
				
			||||||
  {% include 'horizon/common/_domain_page_header.html' with title=_('My OpenStack Deployment') %}
 | 
					  {% include 'horizon/common/_domain_page_header.html' with title=_('My OpenStack Deployment') %}
 | 
				
			||||||
{% endblock page_header %}
 | 
					{% endblock page_header %}
 | 
				
			||||||
@@ -36,7 +29,7 @@
 | 
				
			|||||||
    {% if stack %}
 | 
					    {% if stack %}
 | 
				
			||||||
      {% include "infrastructure/overview/role_nodes_status.html" %}
 | 
					      {% include "infrastructure/overview/role_nodes_status.html" %}
 | 
				
			||||||
    {% else %}
 | 
					    {% else %}
 | 
				
			||||||
      {% include "infrastructure/overview/role_nodes_edit.html" %}
 | 
					      {% include "tuskar_boxes/overview/role_nodes_edit.html" %}
 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
@@ -0,0 +1,205 @@
 | 
				
			|||||||
 | 
					{% load i18n %}
 | 
				
			||||||
 | 
					{% load url from future %}
 | 
				
			||||||
 | 
					{% load form_helpers %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<h4>{% trans "Available Deployment Roles" %}</h4>
 | 
				
			||||||
 | 
					<form method="POST" action="." class="boxes-form">
 | 
				
			||||||
 | 
					{% csrf_token %}
 | 
				
			||||||
 | 
					{% include 'horizon/common/_form_errors.html' with form=form %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="boxes-available-roles">
 | 
				
			||||||
 | 
					{% for role in roles %}{% spaceless %}
 | 
				
			||||||
 | 
					    <div class="boxes-role-{{ role.name|slugify }} boxes-role" data-name="{{ role.name|slugify }}">
 | 
				
			||||||
 | 
					        {{ role.field|add_bootstrap_class }}
 | 
				
			||||||
 | 
					        {{ role.name|title }}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					{% endspaceless %}{% endfor %}
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<h4>{% trans "Available Node Profiles" %}</h4>
 | 
				
			||||||
 | 
					{% for flavor in flavors %}
 | 
				
			||||||
 | 
					<div class="boxes-flavor">
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					        <strong>Node Profile:</strong>
 | 
				
			||||||
 | 
					        <i>{{ flavor.name }}</i>
 | 
				
			||||||
 | 
					        {{ flavor.vcpus }} CPU,
 | 
				
			||||||
 | 
					        {{ flavor.ram }}MB RAM,
 | 
				
			||||||
 | 
					        {{ flavor.disk }}GB Disk
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-xs-5">
 | 
				
			||||||
 | 
					            <div class="boxes-drop-roles">
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="boxes-drop">
 | 
				
			||||||
 | 
					                <i class="fa fa-plus"></i>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-xs-7 boxes-nodes">
 | 
				
			||||||
 | 
					            {% for node in flavor.nodes %}{% spaceless %}
 | 
				
			||||||
 | 
					            <div class="boxes-node">free</div>
 | 
				
			||||||
 | 
					            {% endspaceless %}{% endfor %}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
					{% endfor %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<hr>
 | 
				
			||||||
 | 
					<button type="submit" class="btn btn-default">
 | 
				
			||||||
 | 
					  <i class="fa fa-save"></i>
 | 
				
			||||||
 | 
					  {% trans "Save changes" %}
 | 
				
			||||||
 | 
					</button>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script type="text/javascript">
 | 
				
			||||||
 | 
					(window.$ || window.addHorizonLoadEvent)(function () {
 | 
				
			||||||
 | 
					  function get_role_counts($flavor) {
 | 
				
			||||||
 | 
					    var roles = {};
 | 
				
			||||||
 | 
					    $flavor.find('div.boxes-drop-roles div.boxes-role').each(function () {
 | 
				
			||||||
 | 
					      var $this = $(this);
 | 
				
			||||||
 | 
					      var name = $this.data('name');
 | 
				
			||||||
 | 
					      var count = +$this.find('input.number-picker').val();
 | 
				
			||||||
 | 
					      roles[name] = count;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return roles;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function update_boxes() {
 | 
				
			||||||
 | 
					    $('div.boxes-flavor').each(function () {
 | 
				
			||||||
 | 
					        var $flavor = $(this);
 | 
				
			||||||
 | 
					        var roles = get_role_counts($flavor);
 | 
				
			||||||
 | 
					        var role_names = Object.getOwnPropertyNames(roles);
 | 
				
			||||||
 | 
					        var count = 0;
 | 
				
			||||||
 | 
					        var role = 0;
 | 
				
			||||||
 | 
					        $flavor.find('div.boxes-nodes div.boxes-node').each(function () {
 | 
				
			||||||
 | 
					          var $this = $(this);
 | 
				
			||||||
 | 
					          $this.removeClass('boxes-role-controller boxes-role-compute boxes-role-block-storage boxes-role-object-storage');
 | 
				
			||||||
 | 
					          while (count >= roles[role_names[role]]) {
 | 
				
			||||||
 | 
					            role += 1;
 | 
				
			||||||
 | 
					            count = 0;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (!role_names[role]) {
 | 
				
			||||||
 | 
					            $(this).html('free');
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            $this.addClass('boxes-role-' + role_names[role]).html(' ');
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          count += 1;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  $('div.boxes-role').draggable({
 | 
				
			||||||
 | 
					      revert: 'invalid',
 | 
				
			||||||
 | 
					      helper: 'clone',
 | 
				
			||||||
 | 
					      stack: '.boxes-roles',
 | 
				
			||||||
 | 
					      opacity: 0.5
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  $('div.boxes-drop').droppable({
 | 
				
			||||||
 | 
					      accept: 'div.boxes-role',
 | 
				
			||||||
 | 
					      activeClass: 'boxes-drop-active',
 | 
				
			||||||
 | 
					      hoverClass: 'boxes-drop-hover',
 | 
				
			||||||
 | 
					      tolerance: 'touch',
 | 
				
			||||||
 | 
					      drop: function (ev, ui) {
 | 
				
			||||||
 | 
					        ui.draggable.appendTo($(this).prev('.boxes-drop-roles'));
 | 
				
			||||||
 | 
					        ui.draggable.find('input.number-picker').val(1);
 | 
				
			||||||
 | 
					        window.setTimeout(update_boxes, 0);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  $('div.boxes-available-roles').droppable({
 | 
				
			||||||
 | 
					      accept: 'div.boxes-role',
 | 
				
			||||||
 | 
					      activeClass: 'boxes-drop-active',
 | 
				
			||||||
 | 
					      hoverClass: 'boxes-drop-hover',
 | 
				
			||||||
 | 
					      tolerance: 'touch',
 | 
				
			||||||
 | 
					      drop: function (ev, ui) {
 | 
				
			||||||
 | 
					        ui.draggable.appendTo(this);
 | 
				
			||||||
 | 
					        ui.draggable.find('input.number-picker').val(0);
 | 
				
			||||||
 | 
					        window.setTimeout(update_boxes, 0);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  update_boxes();
 | 
				
			||||||
 | 
					  $('input.number-picker').change(update_boxes);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style type="text/css">
 | 
				
			||||||
 | 
					.boxes-node {
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    width: 60px;
 | 
				
			||||||
 | 
					    height: 60px;
 | 
				
			||||||
 | 
					    border-radius: 2px;
 | 
				
			||||||
 | 
					    border: 1px solid #999;
 | 
				
			||||||
 | 
					    background: #eee;
 | 
				
			||||||
 | 
					    margin: 0 4px 4px 0;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					    color: #666;
 | 
				
			||||||
 | 
					    padding: 20px 4px 0 4px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-available-roles {
 | 
				
			||||||
 | 
					    border-radius: 2px;
 | 
				
			||||||
 | 
					    background: #eee;
 | 
				
			||||||
 | 
					    border: 1px dashed #666;
 | 
				
			||||||
 | 
					    min-height: 42px;
 | 
				
			||||||
 | 
					    min-width: 120px;
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    padding: 4px 0 0 4px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-role {
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    padding: 6px;
 | 
				
			||||||
 | 
					    border: 1px solid;
 | 
				
			||||||
 | 
					    width: 180px;
 | 
				
			||||||
 | 
					    cursor: move;
 | 
				
			||||||
 | 
					    border-radius: 2px;
 | 
				
			||||||
 | 
					    margin: 0 4px 4px 0;
 | 
				
			||||||
 | 
					    background-color: #fce94f;
 | 
				
			||||||
 | 
					    border-color: #edd400;
 | 
				
			||||||
 | 
					    color: #c4a000;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-available-roles .boxes-role {
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					    width: 120px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-available-roles .boxes-role .form-control {
 | 
				
			||||||
 | 
					    display: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-role-controller {
 | 
				
			||||||
 | 
					    background-color: #fcaf3e;
 | 
				
			||||||
 | 
					    border-color: #f57900;
 | 
				
			||||||
 | 
					    color: #ce5c00;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-role-compute {
 | 
				
			||||||
 | 
					    background-color: #8ae234;
 | 
				
			||||||
 | 
					    border-color: #73d216;
 | 
				
			||||||
 | 
					    color: #4e9a06;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-role-object-storage {
 | 
				
			||||||
 | 
					    background-color: #729fcf;
 | 
				
			||||||
 | 
					    border-color: #3465a4;
 | 
				
			||||||
 | 
					    color: #204a87;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-role-block-storage {
 | 
				
			||||||
 | 
					    background-color: #ad7fa8;
 | 
				
			||||||
 | 
					    border-color: #75507b;
 | 
				
			||||||
 | 
					    color: #5c3566;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-drop {
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    padding: 6px;
 | 
				
			||||||
 | 
					    border: 1px dashed;
 | 
				
			||||||
 | 
					    width: 180px;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					    border-radius: 2px;
 | 
				
			||||||
 | 
					    background-color: #eee;
 | 
				
			||||||
 | 
					    border-color: #666;
 | 
				
			||||||
 | 
					    color: #444;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-drop-active {
 | 
				
			||||||
 | 
					    background-color: #ccc;
 | 
				
			||||||
 | 
					    border-style: solid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.boxes-drop-hover {
 | 
				
			||||||
 | 
					    background-color: #999;
 | 
				
			||||||
 | 
					    border-style: solid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user