diff options
27 files changed, 281 insertions, 139 deletions
diff --git a/dev_env.sh b/dev_env.sh new file mode 100644 index 00000000..020cc2a5 --- /dev/null +++ b/dev_env.sh @@ -0,0 +1,56 @@ +#!/bin/bash +set -ex + +USAGE="Usage: `basename $0` <undercloud_ip> <undercloud_admin_password>" + +if [ "$#" -ne 2 ]; then + echo $USAGE + exit 1 +fi + +UNDERCLOUD_IP=$1 +UNDERCLOUD_ADMIN_PASSWORD=$2 + +echo "Copying SSH key..." +cp /home/stack/.ssh/id_rsa /root/.ssh/ + +echo "Installing system requirements..." +yum install -y git python-devel swig openssl-devel mysql-devel libxml2-devel libxslt-devel gcc gcc-c++ +easy_install pip nose + +echo "Cloning repos..." +mkdir /opt/stack +cd /opt/stack +git clone git://github.com/openstack/horizon.git +git clone git://github.com/openstack/python-tuskarclient.git +git clone git://github.com/openstack/tuskar-ui.git +git clone git://github.com/rdo-management/tuskar-ui-extras.git + +echo "Setting up repos..." +cd horizon +python tools/install_venv.py +./run_tests.sh -V +cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py +tools/with_venv.sh pip install -e ../python-tuskarclient/ +tools/with_venv.sh pip install -e ../tuskar-ui/ +tools/with_venv.sh pip install -e ../tuskar-ui-extras/ +cp ../tuskar-ui/_50_tuskar.py.example openstack_dashboard/local/enabled/_50_tuskar.py +cp ../tuskar-ui-extras/_60_tuskar_boxes.py.example openstack_dashboard/local/enabled/_60_tuskar_boxes.py +cp ../tuskar-ui/_10_admin.py.example openstack_dashboard/local/enabled/_10_admin.py +cp ../tuskar-ui/_20_project.py.example openstack_dashboard/local/enabled/_20_project.py +cp ../tuskar-ui/_30_identity.py.example openstack_dashboard/local/enabled/_30_identity.py +sed -i s/'OPENSTACK_HOST = "127.0.0.1"'/'OPENSTACK_HOST = "192.0.2.1"'/ openstack_dashboard/local/local_settings.py +echo 'IRONIC_DISCOVERD_URL = "http://%s:5050" % OPENSTACK_HOST' >> openstack_dashboard/local/local_settings.py +echo 'UNDERCLOUD_ADMIN_PASSWORD = "'$UNDERCLOUD_ADMIN_PASSWORD'"' >> openstack_dashboard/local/local_settings.py +echo 'DEPLOYMENT_MODE = "scale"' >> openstack_dashboard/local/local_settings.py + +echo "Setting up networking..." +sudo ip route replace 192.0.2.0/24 dev virbr0 via $UNDERCLOUD_IP + +echo "Setting up iptables on the undercloud..." +RULE_1="-A INPUT -p tcp -m tcp --dport 8585 -j ACCEPT" +RULE_2="-A INPUT -p tcp -m tcp --dport 9696 -j ACCEPT" +RULE_3="-A INPUT -p tcp -m tcp --dport 8777 -j ACCEPT" +ssh $UNDERCLOUD_IP "sed -i '/$RULE_1/a $RULE_2' /etc/sysconfig/iptables" +ssh $UNDERCLOUD_IP "sed -i '/$RULE_2/a $RULE_3' /etc/sysconfig/iptables" +ssh $UNDERCLOUD_IP "service iptables restart" @@ -25,5 +25,5 @@ except ImportError: pass setuptools.setup( - setup_requires=['pbr'], + setup_requires=['pbr>=1.3'], pbr=True) diff --git a/test-requirements.txt b/test-requirements.txt index c2dedb5a..bc873bfc 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -20,7 +20,7 @@ http://tarballs.openstack.org/python-tuskarclient/python-tuskarclient-master.tar coverage>=3.6 django-nose>=1.2 -mock>=1.0 +mock>=1.2 mox>=0.5.3 mox3>=0.7.0 nodeenv>=0.9.4 # BSD License diff --git a/tuskar_ui/api/heat.py b/tuskar_ui/api/heat.py index 9852ca00..923565ec 100644 --- a/tuskar_ui/api/heat.py +++ b/tuskar_ui/api/heat.py @@ -429,12 +429,14 @@ class Stack(base.APIResourceWrapper): if not client: return [] - services = client.services.list() - - for service in services: - if service.name == 'horizon': - break - else: + try: + services = client.services.list() + for service in services: + if service.name == 'horizon': + break + else: + return [] + except Exception: return [] admin_urls = [endpoint.adminurl for endpoint diff --git a/tuskar_ui/api/node.py b/tuskar_ui/api/node.py index 2f67ae78..2ad65195 100644 --- a/tuskar_ui/api/node.py +++ b/tuskar_ui/api/node.py @@ -11,6 +11,7 @@ # under the License. import logging +import time from django.conf import settings from django.utils.translation import ugettext_lazy as _ @@ -266,6 +267,11 @@ class Node(base.APIResourceWrapper): for uuid in uuids: discoverd_client.introspect(uuid, IRONIC_DISCOVERD_URL, request.user.token.id) + # NOTE(dtantsur): PXE firmware on virtual machines misbehaves when + # a lot of nodes start DHCPing simultaneously: it ignores NACK from + # DHCP server, tries to get the same address, then times out. Work + # around it by using sleep, anyway introspection takes much longer. + time.sleep(5) @classmethod def set_maintenance(cls, request, uuid, maintenance): diff --git a/tuskar_ui/api/tuskar.py b/tuskar_ui/api/tuskar.py index 85d293eb..89244591 100644 --- a/tuskar_ui/api/tuskar.py +++ b/tuskar_ui/api/tuskar.py @@ -256,7 +256,7 @@ class Plan(base.APIResourceWrapper): key_params = [] for role in self.role_list: key_params.extend([role.node_count_parameter_name, - role.image_id_parameter_name, + role.image_parameter_name, role.flavor_parameter_name]) params = [p for p in params if p['name'] not in key_params] return [Parameter(p, plan=self) for p in params] @@ -389,9 +389,17 @@ class Role(base.APIResourceWrapper): @classmethod @memoized.memoized - def _roles_by_image_id(cls, request, plan): - return {plan.parameter_value(role.image_id_parameter_name): role - for role in Role.list(request)} + def _roles_by_image(cls, request, plan): + roles_by_image = {} + + for role in Role.list(request): + image = plan.parameter_value(role.image_parameter_name) + if image in roles_by_image: + roles_by_image[image].append(role) + else: + roles_by_image[image] = [role] + + return roles_by_image @classmethod @handle_errors(_("Unable to retrieve overcloud role")) @@ -411,11 +419,11 @@ class Role(base.APIResourceWrapper): Role can be found :rtype: tuskar_ui.api.tuskar.Role """ - roles = cls._roles_by_image_id(request, plan) + roles = cls._roles_by_image(request, plan) try: - return roles[image.id] + return roles[image.name] except KeyError: - return None + return [] @classmethod @memoized.memoized @@ -445,7 +453,7 @@ class Role(base.APIResourceWrapper): return self.parameter_prefix + 'count' @property - def image_id_parameter_name(self): + def image_parameter_name(self): return self.parameter_prefix + 'Image' @property @@ -453,12 +461,13 @@ class Role(base.APIResourceWrapper): return self.parameter_prefix + 'Flavor' def image(self, plan): - image_id = plan.parameter_value(self.image_id_parameter_name) - if image_id: + image_name = plan.parameter_value(self.image_parameter_name) + if image_name: try: - return glance.image_get(self._request, image_id) - except glance_exceptions.HTTPNotFound: - LOG.error("Couldn't obtain image with id %s" % image_id) + return glance.image_list_detailed( + self._request, filters={'name': image_name})[0][0] + except (glance_exceptions.HTTPNotFound, IndexError): + LOG.error("Couldn't obtain image with name %s" % image_name) return None def flavor(self, plan): diff --git a/tuskar_ui/infrastructure/images/tables.py b/tuskar_ui/infrastructure/images/tables.py index 8bd8bbf4..bbc8c0a9 100644 --- a/tuskar_ui/infrastructure/images/tables.py +++ b/tuskar_ui/infrastructure/images/tables.py @@ -61,9 +61,9 @@ class ImagesTable(tables.DataTable): verbose_name=_("Image Name")) disk_format = tables.Column('disk_format', verbose_name=_("Format")) - role = tables.Column(lambda image: - image.role.name if image.role else '-', - verbose_name=_("Deployment Role")) + roles = tables.Column(lambda image: + ', '.join([r.name for r in image.roles]), + verbose_name=_("Deployment Roles")) class Meta(object): name = "images" diff --git a/tuskar_ui/infrastructure/images/views.py b/tuskar_ui/infrastructure/images/views.py index b18e0634..198fdf43 100644 --- a/tuskar_ui/infrastructure/images/views.py +++ b/tuskar_ui/infrastructure/images/views.py @@ -57,7 +57,7 @@ class IndexView(infrastructure_views.ItemCountMixin, plan = tuskar_api.tuskar.Plan.get_the_plan(self.request) for image in images: - image.role = tuskar_api.tuskar.Role.get_by_image( + image.roles = tuskar_api.tuskar.Role.get_by_image( self.request, plan, image) return images diff --git a/tuskar_ui/infrastructure/nodes/tests.py b/tuskar_ui/infrastructure/nodes/tests.py index 4f91bb9e..485a31b4 100644 --- a/tuskar_ui/infrastructure/nodes/tests.py +++ b/tuskar_ui/infrastructure/nodes/tests.py @@ -162,8 +162,8 @@ class NodesTests(test.BaseAdminViewTests): 'register_nodes-0-cpus': '1', 'register_nodes-0-memory_mb': '2', 'register_nodes-0-local_gb': '3', - 'register_nodes-0-deployment_kernel': images[6].id, - 'register_nodes-0-deployment_ramdisk': images[7].id, + 'register_nodes-0-deployment_kernel': images[3].id, + 'register_nodes-0-deployment_ramdisk': images[4].id, 'register_nodes-1-driver': 'pxe_ipmitool', 'register_nodes-1-ipmi_address': '127.0.0.2', @@ -172,8 +172,8 @@ class NodesTests(test.BaseAdminViewTests): 'register_nodes-1-cpus': '4', 'register_nodes-1-memory_mb': '5', 'register_nodes-1-local_gb': '6', - 'register_nodes-1-deployment_kernel': images[6].id, - 'register_nodes-1-deployment_ramdisk': images[7].id, + 'register_nodes-1-deployment_kernel': images[3].id, + 'register_nodes-1-deployment_ramdisk': images[4].id, } with mock.patch('tuskar_ui.api.node.Node', **{ 'spec_set': ['create', 'get_all_mac_addresses'], @@ -198,8 +198,8 @@ class NodesTests(test.BaseAdminViewTests): ipmi_username=u'username', ipmi_password=u'password', driver='pxe_ipmitool', - deployment_kernel=images[6].id, - deployment_ramdisk=images[7].id, + deployment_kernel=images[3].id, + deployment_ramdisk=images[4].id, ), mock.call( mock.ANY, @@ -212,8 +212,8 @@ class NodesTests(test.BaseAdminViewTests): ipmi_username=None, ipmi_password=None, driver='pxe_ipmitool', - deployment_kernel=images[6].id, - deployment_ramdisk=images[7].id, + deployment_kernel=images[3].id, + deployment_ramdisk=images[4].id, ), ]) @@ -234,8 +234,8 @@ class NodesTests(test.BaseAdminViewTests): 'register_nodes-0-cpus': '1', 'register_nodes-0-memory_mb': '2', 'register_nodes-0-local_gb': '3', - 'register_nodes-0-deployment_kernel': images[6].id, - 'register_nodes-0-deployment_ramdisk': images[7].id, + 'register_nodes-0-deployment_kernel': images[3].id, + 'register_nodes-0-deployment_ramdisk': images[4].id, 'register_nodes-1-driver': 'pxe_ipmitool', 'register_nodes-1-ipmi_address': '127.0.0.2', @@ -244,8 +244,8 @@ class NodesTests(test.BaseAdminViewTests): 'register_nodes-1-cpus': '4', 'register_nodes-1-memory_mb': '5', 'register_nodes-1-local_gb': '6', - 'register_nodes-1-deployment_kernel': images[6].id, - 'register_nodes-1-deployment_ramdisk': images[7].id, + 'register_nodes-1-deployment_kernel': images[3].id, + 'register_nodes-1-deployment_ramdisk': images[4].id, } with mock.patch('tuskar_ui.api.node.Node', **{ 'spec_set': ['create', 'get_all_mac_addresses'], @@ -269,8 +269,8 @@ class NodesTests(test.BaseAdminViewTests): ipmi_username=u'username', ipmi_password=u'password', driver='pxe_ipmitool', - deployment_kernel=images[6].id, - deployment_ramdisk=images[7].id, + deployment_kernel=images[3].id, + deployment_ramdisk=images[4].id, ), mock.call( mock.ANY, @@ -283,8 +283,8 @@ class NodesTests(test.BaseAdminViewTests): ipmi_username=None, ipmi_password=None, driver='pxe_ipmitool', - deployment_kernel=images[6].id, - deployment_ramdisk=images[7].id, + deployment_kernel=images[3].id, + deployment_ramdisk=images[4].id, ), ]) self.assertTemplateUsed( diff --git a/tuskar_ui/infrastructure/overview/forms.py b/tuskar_ui/infrastructure/overview/forms.py index ff78123e..77ff8c37 100644 --- a/tuskar_ui/infrastructure/overview/forms.py +++ b/tuskar_ui/infrastructure/overview/forms.py @@ -412,6 +412,9 @@ class PostDeployInit(horizon.forms.SelfHandlingForm): "cinder": { "password": plan.parameter_value( controller_role.parameter_prefix + 'CinderPassword')}, + "cinderv2": { + "password": plan.parameter_value( + controller_role.parameter_prefix + 'CinderPassword')}, "ec2": { "password": plan.parameter_value( controller_role.parameter_prefix + 'GlancePassword')}, diff --git a/tuskar_ui/infrastructure/overview/tests.py b/tuskar_ui/infrastructure/overview/tests.py index 760f193c..20155c86 100644 --- a/tuskar_ui/infrastructure/overview/tests.py +++ b/tuskar_ui/infrastructure/overview/tests.py @@ -278,6 +278,7 @@ class OverviewTests(test.BaseAdminViewTests): 'path': '/', 'admin_path': '/admin'}, 'cinder': {'password': None}, + 'cinderv2': {'password': None}, 'glance': {'password': None}, 'swift': {'password': None, 'path': '/v1/AUTH_%(tenant_id)s', diff --git a/tuskar_ui/infrastructure/overview/urls.py b/tuskar_ui/infrastructure/overview/urls.py index 6e409a6b..35410d5d 100644 --- a/tuskar_ui/infrastructure/overview/urls.py +++ b/tuskar_ui/infrastructure/overview/urls.py @@ -32,4 +32,7 @@ urlpatterns = urls.patterns( urls.url(r'^scale-out$', views.ScaleOutView.as_view(), name='scale_out'), + urls.url(r'^download-overcloudrc$', + views.download_overcloudrc_file, + name='download_overcloudrc'), ) diff --git a/tuskar_ui/infrastructure/overview/views.py b/tuskar_ui/infrastructure/overview/views.py index 970725c8..90f9fa37 100644 --- a/tuskar_ui/infrastructure/overview/views.py +++ b/tuskar_ui/infrastructure/overview/views.py @@ -13,14 +13,18 @@ # under the License. import json +import logging +import urlparse from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse_lazy from django import http +from django import shortcuts import django.utils.text from django.utils.translation import ugettext_lazy as _ import heatclient import horizon.forms +from horizon import messages from tuskar_ui import api from tuskar_ui.infrastructure.overview import forms @@ -29,6 +33,8 @@ from tuskar_ui.infrastructure import views INDEX_URL = 'horizon:infrastructure:overview:index' +LOG = logging.getLogger(__name__) + def _steps_message(messages): total_steps = len(messages) @@ -218,6 +224,10 @@ class IndexView(horizon.forms.ModalFormView, views.StackMixin): controller_role.parameter_prefix + 'AdminPassword') context['dashboard_urls'] = stack.dashboard_urls + no_proxy = [urlparse.urlparse(url).hostname + for url in stack.dashboard_urls] + context['no_proxy'] = ",".join(no_proxy) + context['auth_url'] = stack.keystone_auth_url else: messages = forms.validate_plan(request, plan) context['plan_messages'] = messages @@ -344,3 +354,37 @@ class ScaleOutView(horizon.forms.ModalFormView, views.StackMixin): 'plan': plan, }) return context + + +def _get_openrc_credentials(request): + plan = api.tuskar.Plan.get_the_plan(request) + stack = api.heat.Stack.get_by_plan(request, plan) + no_proxy = [urlparse.urlparse(url).hostname + for url in stack.dashboard_urls] + controller_role = plan.get_role_by_name("Controller") + credentials = dict(tenant_name='admin', + auth_url=stack.keystone_auth_url, + admin_password=plan.parameter_value( + controller_role.parameter_prefix + 'AdminPassword'), + no_proxy=",".join(no_proxy)) + return credentials + + +def download_overcloudrc_file(request): + template = 'infrastructure/overview/overcloudrc.sh.template' + try: + context = _get_openrc_credentials(request) + + response = shortcuts.render(request, + template, + context, + content_type="text/plain") + response['Content-Disposition'] = ('attachment; ' + 'filename="overcloudrc"') + response['Content-Length'] = str(len(response.content)) + return response + + except Exception as e: + LOG.exception("Exception in DownloadOvercloudrcForm.") + messages.error(request, _('Error Downloading RC File: %s') % e) + return shortcuts.redirect(request.build_absolute_uri()) diff --git a/tuskar_ui/infrastructure/parameters/forms.py b/tuskar_ui/infrastructure/parameters/forms.py index cc31df57..e0c0609d 100644 --- a/tuskar_ui/infrastructure/parameters/forms.py +++ b/tuskar_ui/infrastructure/parameters/forms.py @@ -136,7 +136,11 @@ class AdvancedEditServiceConfig(ServiceConfig): def handle(self, request, data): plan = api.tuskar.Plan.get_the_plan(self.request) - data = self._sync_common_params_across_roles(plan, data) + + # TODO(bcrochet): Commenting this out. + # For advanced config, we should have a whitelist of which params + # must be synced across roles. + # data = self._sync_common_params_across_roles(plan, data) try: plan.patch(request, plan.uuid, data) diff --git a/tuskar_ui/infrastructure/roles/tests.py b/tuskar_ui/infrastructure/roles/tests.py index 55cba9d8..d9ee2057 100644 --- a/tuskar_ui/infrastructure/roles/tests.py +++ b/tuskar_ui/infrastructure/roles/tests.py @@ -48,15 +48,15 @@ class RolesTest(test.BaseAdminViewTests): plans = [api.tuskar.Plan(plan) for plan in self.tuskarclient_plans.list()] flavor = self.novaclient_flavors.first() - image = self.glanceclient_images.first() + images = self.glanceclient_images.list() with contextlib.nested( patch('tuskar_ui.api.tuskar.Plan.list', return_value=plans), patch('tuskar_ui.api.tuskar.Role.list', return_value=roles), - patch('openstack_dashboard.api.glance.image_get', - return_value=image), + patch('openstack_dashboard.api.glance.image_list_detailed', + return_value=[images]), patch('tuskar_ui.api.flavor.Flavor.get_by_name', return_value=flavor)): res = self.client.get(INDEX_URL) @@ -69,7 +69,7 @@ class RolesTest(test.BaseAdminViewTests): plans = [api.tuskar.Plan(plan) for plan in self.tuskarclient_plans.list()] flavor = self.novaclient_flavors.first() - image = self.glanceclient_images.first() + images = self.glanceclient_images.list() stack = api.heat.Stack(TEST_DATA.heatclient_stacks.first()) with contextlib.nested( @@ -83,8 +83,8 @@ class RolesTest(test.BaseAdminViewTests): return_value=[]), patch('tuskar_ui.api.tuskar.Plan.list', return_value=plans), - patch('openstack_dashboard.api.glance.image_get', - return_value=image), + patch('openstack_dashboard.api.glance.image_list_detailed', + return_value=[images]), patch('tuskar_ui.api.flavor.Flavor.get_by_name', return_value=flavor)): res = self.client.get(DETAIL_URL) @@ -137,7 +137,7 @@ class RolesTest(test.BaseAdminViewTests): 'name': 'controller', 'description': 'The controller node role.', 'flavor': self.novaclient_flavors.first().name, - 'image': self.glanceclient_images.first().id, + 'image': self.glanceclient_images.first().name, 'nodes': '0', } @@ -163,4 +163,4 @@ class RolesTest(test.BaseAdminViewTests): args = mock_patch.call_args_list[0][0] self.assertEqual(args[1], plan.id) self.assertEqual(args[2]['Controller-1::Flavor'], u'flavor-1') - self.assertEqual(args[2]['Controller-1::Image'], u'2') + self.assertEqual(args[2]['Controller-1::Image'], u'overcloud-full') diff --git a/tuskar_ui/infrastructure/roles/views.py b/tuskar_ui/infrastructure/roles/views.py index 78a73065..b5cb5801 100644 --- a/tuskar_ui/infrastructure/roles/views.py +++ b/tuskar_ui/infrastructure/roles/views.py @@ -143,7 +143,7 @@ class UpdateView(workflows.WorkflowView, views.StackMixin, views.RoleMixin): role_flavor = '' if role_flavor is None else role_flavor.name role_image = role.image(plan) - role_image = '' if role_image is None else role_image.id + role_image = '' if role_image is None else role_image.name free_nodes = len(api.node.Node.list(self.request, associated=False, maintenance=False)) diff --git a/tuskar_ui/infrastructure/roles/workflows.py b/tuskar_ui/infrastructure/roles/workflows.py index 2a138c10..b9786112 100644 --- a/tuskar_ui/infrastructure/roles/workflows.py +++ b/tuskar_ui/infrastructure/roles/workflows.py @@ -78,7 +78,7 @@ class UpdateRoleInfoAction(workflows.Action): images = [image for image in images if tuskar_utils.check_image_type(image, 'overcloud provisioning')] - choices = [(i.id, i.name) for i in images] + choices = [(i.name, i.name) for i in images] return [('', _('Unknown'))] + choices def clean_nodes(self): @@ -170,7 +170,7 @@ class UpdateRole(workflows.Workflow): redirect=reverse_lazy(self.index_url)) parameters = data['parameters'] - parameters[role.image_id_parameter_name] = data['image'] + parameters[role.image_parameter_name] = data['image'] parameters[role.node_count_parameter_name] = data['nodes'] if utils.matching_deployment_mode(): parameters[role.flavor_parameter_name] = data['flavor'] diff --git a/tuskar_ui/infrastructure/static/infrastructure/js/tuskar.deployment_live.js b/tuskar_ui/infrastructure/static/infrastructure/js/tuskar.deployment_live.js new file mode 100644 index 00000000..22e4f2f5 --- /dev/null +++ b/tuskar_ui/infrastructure/static/infrastructure/js/tuskar.deployment_live.js @@ -0,0 +1,17 @@ +tuskar.deployment_live = (function () { + 'use strict'; + + var module = {}; + + module.init = function () { + $("#overcloudrc").on("hide.bs.collapse", function(){ + $("span.overcloudrc").html('Show <i class="fa fa-angle-down"></i>'); + }); + $("#overcloudrc").on("show.bs.collapse", function(){ + $("span.overcloudrc").html('Hide <i class="fa fa-angle-up"></i>'); + }); + }; + + horizon.addInitFunction(module.init); + return module; +} ()); diff --git a/tuskar_ui/infrastructure/templates/infrastructure/_scripts.html b/tuskar_ui/infrastructure/templates/infrastructure/_scripts.html index 61d91811..ff190f01 100644 --- a/tuskar_ui/infrastructure/templates/infrastructure/_scripts.html +++ b/tuskar_ui/infrastructure/templates/infrastructure/_scripts.html @@ -10,6 +10,7 @@ <script src='{{ STATIC_URL }}infrastructure/js/tuskar.edit_plan.js' type='text/javascript' charset='utf-8'></script> <script src='{{ STATIC_URL }}infrastructure/js/tuskar.deployment_progress.js' type='text/javascript' charset='utf-8'></script> <script src='{{ STATIC_URL }}infrastructure/js/tuskar.performance.js' type='text/javascript' charset='utf-8'></script> + <script src='{{ STATIC_URL }}infrastructure/js/tuskar.deployment_live.js' type='text/javascript' charset='utf-8'></script> {% endblock %} {% comment %} Tuskar-UI Client-side Templates (These should *not* be inside the "compress" tag.) {% endcomment %} diff --git a/tuskar_ui/infrastructure/templates/infrastructure/overview/deployment_base.html b/tuskar_ui/infrastructure/templates/infrastructure/overview/deployment_base.html index b8065a6d..04bf8eef 100644 --- a/tuskar_ui/infrastructure/templates/infrastructure/overview/deployment_base.html +++ b/tuskar_ui/infrastructure/templates/infrastructure/overview/deployment_base.html @@ -22,4 +22,6 @@ </div> </div> +{% block deployment-overcloudrc %}{% endblock %} + {% block templates %}{% endblock %} diff --git a/tuskar_ui/infrastructure/templates/infrastructure/overview/deployment_live.html b/tuskar_ui/infrastructure/templates/infrastructure/overview/deployment_live.html index 9d371641..af6dfa81 100644 --- a/tuskar_ui/infrastructure/templates/infrastructure/overview/deployment_live.html +++ b/tuskar_ui/infrastructure/templates/infrastructure/overview/deployment_live.html @@ -56,3 +56,58 @@ </a> {% endblock %} + +{% block deployment-overcloudrc %} + <div class="clear"></div> + <div class="deployment-icon"> + <i class="fa fa-key fa-3x fa-fw"></i> + </div> + <div class="deployment-box clearfix"> + <h4>{% trans "Overcloudrc Information" %}</h4><a data-toggle="collapse" href="#overcloudrc" aria-expanded="false" aria-controls="overcloudrc" id="collapse-rc"><span class='overcloudrc'>{% trans "Show" %}<i class="fa fa-angle-down"></i></span></a> + <div class="collapse" id="overcloudrc"> + <div class="row"> + <div class="col-xs-4">NOVA_VERSION:</div> + <div class="col-xs-8">1.1</div> + </div> + <div class="row"> + <div class="col-xs-4">OS_USERNAME:</div> + <div class="col-xs-8">admin</div> + </div> + <div class="row"> + <div class="col-xs-4">OS_PASSWORD:</div> + <div class="col-xs-8">{{ admin_password }}</div> + </div> + <div class="row"> + <div class="col-xs-4">OS_AUTH_URL:</div> + <div class="col-xs-8">{{ auth_url }}</div> + </div> + <div class="row"> + <div class="col-xs-4">OS_TENANT_NAME:</div> + <div class="col-xs-8">admin</div> + </div> + <div class="row"> + <div class="col-xs-4">COMPUTE_API_VERSION:</div> + <div class="col-xs-8">1.1</div> + </div> + <div class="row"> + <div class="col-xs-4">OS_NO_CACHE:</div> + <div class="col-xs-8">True</div> + </div> + <div class="row"> + <div class="col-xs-4">no_proxy:</div> + <div class="col-xs-8">{{ no_proxy }}</div> + </div> + <div class="row"> + <div class="col-xs-4">{% trans "Download" %}</div> + <div class="col-xs-8"> + <a + href="{% url 'horizon:infrastructure:overview:download_overcloudrc' %}" + class="btn btn-default" + > + <i class="fa fa-lg fa-download"></i> {% trans "Download" %} + </a> + </div> + </div> + </div> + </div> +{% endblock %} diff --git a/tuskar_ui/infrastructure/templates/infrastructure/overview/overcloudrc.sh.template b/tuskar_ui/infrastructure/templates/infrastructure/overview/overcloudrc.sh.template new file mode 100644 index 00000000..5977bb37 --- /dev/null +++ b/tuskar_ui/infrastructure/templates/infrastructure/overview/overcloudrc.sh.template @@ -0,0 +1,9 @@ +#!/bin/bash +export NOVA_VERSION=1.1 +export OS_AUTH_URL={{ auth_url }} +export OS_TENANT_NAME="admin" +export OS_USERNAME="admin" +export OS_PASSWORD={{ admin_password }} +export COMPUTE_API_VERSION=1.1 +export OS_NO_CACHE=True +export no_proxy={{ no_proxy }} diff --git a/tuskar_ui/infrastructure/templatetags/context_selection.py b/tuskar_ui/infrastructure/templatetags/context_selection.py deleted file mode 100644 index 8b29d805..00000000 --- a/tuskar_ui/infrastructure/templatetags/context_selection.py +++ /dev/null @@ -1,41 +0,0 @@ -# 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() - -# Overwrite the selector code from OpenStack Dashboard, so that the -# selector doesn't appear. - - -@register.simple_tag() -def show_overview(*args, **kwargs): - return '<span class="context-overview"></span>' - - -@register.simple_tag() -def show_domain_list(*args, **kwargs): - return '' - - -@register.simple_tag() -def show_project_list(*args, **kwargs): - return '' - - -@register.simple_tag() -def show_region_list(*args, **kwargs): - return '' diff --git a/tuskar_ui/test/api_tests/node_tests.py b/tuskar_ui/test/api_tests/node_tests.py index 2589caab..7bde594b 100644 --- a/tuskar_ui/test/api_tests/node_tests.py +++ b/tuskar_ui/test/api_tests/node_tests.py @@ -158,4 +158,4 @@ class NodeAPITests(test.APITestCase): return_value=([instance], False), ): ret_val = api.node.Node(node).image_name - self.assertEqual(ret_val, 'overcloud-control') + self.assertEqual(ret_val, 'overcloud-full') diff --git a/tuskar_ui/test/api_tests/tuskar_tests.py b/tuskar_ui/test/api_tests/tuskar_tests.py index 16526a81..3979bd73 100644 --- a/tuskar_ui/test/api_tests/tuskar_tests.py +++ b/tuskar_ui/test/api_tests/tuskar_tests.py @@ -108,8 +108,8 @@ class TuskarAPITests(test.APITestCase): return_value=roles): ret_val = api.tuskar.Role.get_by_image( self.request, plan, image) - self.assertIsInstance(ret_val, api.tuskar.Role) - self.assertEqual(ret_val.name, 'Controller') + self.assertIsInstance(ret_val, list) + self.assertEqual(len(ret_val), 3) def test_parameter_stripped_name(self): plan = api.tuskar.Plan(self.tuskarclient_plans.first()) diff --git a/tuskar_ui/test/test_data/heat_data.py b/tuskar_ui/test/test_data/heat_data.py index d99908fc..303bcc0a 100644 --- a/tuskar_ui/test/test_data/heat_data.py +++ b/tuskar_ui/test/test_data/heat_data.py @@ -202,75 +202,47 @@ def data(TEST): TEST.glanceclient_images = test_data_utils.TestDataContainer() image_1 = images.Image( images.ImageManager(None), - {'id': '2', - 'name': 'overcloud-control', - 'is_public': True, - 'protected': False, - 'properties': { - 'type': 'overcloud provisioning' - }}) - image_2 = images.Image( - images.ImageManager(None), {'id': '1', - 'name': 'overcloud-compute', - 'is_public': True, - 'protected': False, - 'properties': { - 'type': 'overcloud provisioning' - }}) - image_3 = images.Image( - images.ImageManager(None), - {'id': '3', - 'name': 'Object Storage Image', - 'is_public': True, - 'protected': False, - 'properties': { - 'type': 'overcloud provisioning' - }}) - image_4 = images.Image( - images.ImageManager(None), - {'id': '4', - 'name': 'Block Storage Image', + 'name': 'overcloud-full', 'is_public': True, 'protected': False, 'properties': { 'type': 'overcloud provisioning' }}) - image_5 = images.Image( + image_2 = images.Image( images.ImageManager(None), - {'id': '5', + {'id': '2', 'name': 'Discovery Ramdisk', 'is_public': True, 'protected': False, 'properties': { 'type': 'discovery ramdisk' }}) - image_6 = images.Image( + image_3 = images.Image( images.ImageManager(None), - {'id': '6', + {'id': '3', 'name': 'Discovery Kernel', 'is_public': True, 'protected': False, 'properties': { 'type': 'discovery kernel' }}) - image_7 = images.Image( + image_4 = images.Image( images.ImageManager(None), - {'id': '7', + {'id': '4', 'name': 'Baremetal Deployment Kernel', 'is_public': True, 'protected': False, 'properties': { 'type': 'deploy kernel' }}) - image_8 = images.Image( + image_5 = images.Image( images.ImageManager(None), - {'id': '8', + {'id': '5', 'name': 'Baremetal Deployment Ramdisk', 'is_public': True, 'protected': False, 'properties': { 'type': 'deploy ramdisk' }}) - TEST.glanceclient_images.add(image_1, image_2, image_3, image_4, - image_5, image_6, image_7, image_8) + TEST.glanceclient_images.add(image_1, image_2, image_3, image_4, image_5) diff --git a/tuskar_ui/test/test_data/tuskar_data.py b/tuskar_ui/test/test_data/tuskar_data.py index c1913180..dae72f1c 100644 --- a/tuskar_ui/test/test_data/tuskar_data.py +++ b/tuskar_ui/test/test_data/tuskar_data.py @@ -29,7 +29,6 @@ def data(TEST): 'template': '', 'created_at': '2014-05-27T21:11:09Z', 'modified_at': '2014-05-30T21:11:09Z', - 'uuid': '1234567890', 'roles': [ { 'uuid': 'role-1', @@ -108,7 +107,7 @@ def data(TEST): 'description': 'Controller image ID', 'hidden': False, 'default': '', - 'value': '2', + 'value': 'overcloud-full', 'parameter_type': 'string', 'constraints': [], }, { @@ -117,7 +116,7 @@ def data(TEST): 'description': 'Compute image ID', 'hidden': False, 'default': '', - 'value': '1', + 'value': 'overcloud-full', 'parameter_type': 'string', 'constraints': [], }, { @@ -126,7 +125,7 @@ def data(TEST): 'description': 'Block storage image ID', 'hidden': False, 'default': '', - 'value': '4', + 'value': 'overcloud-full', 'parameter_type': 'string', 'constraints': [], }, { |