diff options
Diffstat (limited to 'tuskar_ui/infrastructure/overview/forms.py')
-rw-r--r-- | tuskar_ui/infrastructure/overview/forms.py | 488 |
1 files changed, 0 insertions, 488 deletions
diff --git a/tuskar_ui/infrastructure/overview/forms.py b/tuskar_ui/infrastructure/overview/forms.py deleted file mode 100644 index 77ff8c37..00000000 --- a/tuskar_ui/infrastructure/overview/forms.py +++ /dev/null @@ -1,488 +0,0 @@ -# -*- coding: utf8 -*- -# -# 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. - -import logging -import six -import uuid - -from django.conf import settings -import django.forms -from django.utils.translation import ugettext_lazy as _ -import horizon.exceptions -import horizon.forms -import horizon.messages -from os_cloud_config import keystone as keystone_config -from os_cloud_config.utils import clients - -from tuskar_ui import api -import tuskar_ui.api.heat -import tuskar_ui.api.tuskar -import tuskar_ui.forms -import tuskar_ui.infrastructure.flavors.utils as flavors_utils -import tuskar_ui.utils.utils as tuskar_utils - -MATCHING_DEPLOYMENT_MODE = flavors_utils.matching_deployment_mode() -LOG = logging.getLogger(__name__) -MESSAGE_ICONS = { - 'ok': 'fa-check-square-o text-success', - 'pending': 'fa-square-o text-info', - 'error': 'fa-exclamation-circle text-danger', - 'warning': 'fa-exclamation-triangle text-warning', - None: 'fa-exclamation-triangle text-warning', -} -WEBROOT = getattr(settings, 'WEBROOT', '/') - - -def validate_roles(request, plan): - """Validates the roles in plan and returns dict describing the issues""" - for role in plan.role_list: - if ( - plan.get_role_node_count(role) and - not role.is_valid_for_deployment(plan) - ): - message = { - 'text': _(u"Configure Roles."), - 'is_critical': True, - 'status': 'pending', - } - break - else: - message = { - 'text': _(u"Configure Roles."), - 'status': 'ok', - } - return message - - -def validate_global_parameters(request, plan): - pending_required_global_params = list( - api.tuskar.Parameter.pending_parameters( - api.tuskar.Parameter.required_parameters( - api.tuskar.Parameter.global_parameters( - plan.parameter_list())))) - if pending_required_global_params: - message = { - 'text': _(u"Global Service Configuration."), - 'is_critical': True, - 'status': 'pending', - } - else: - message = { - 'text': _(u"Global Service Configuration."), - 'status': 'ok', - } - return message - - -def validate_plan(request, plan): - """Validates the plan and returns a list of dicts describing the issues.""" - messages = [] - requested_nodes = 0 - for role in plan.role_list: - node_count = plan.get_role_node_count(role) - requested_nodes += node_count - available_flavors = len(api.flavor.Flavor.list(request)) - if available_flavors == 0: - messages.append({ - 'text': _(u"Define Flavors."), - 'is_critical': True, - 'status': 'pending', - }) - else: - messages.append({ - 'text': _(u"Define Flavors."), - 'status': 'ok', - }) - available_nodes = len(api.node.Node.list(request, associated=False, - maintenance=False)) - if available_nodes == 0: - messages.append({ - 'text': _(u"Register Nodes."), - 'is_critical': True, - 'status': 'pending', - }) - elif requested_nodes > available_nodes: - messages.append({ - 'text': _(u"Not enough registered nodes for this plan. " - u"You need {0} more.").format( - requested_nodes - available_nodes), - 'is_critical': True, - 'status': 'error', - }) - else: - messages.append({ - 'text': _(u"Register Nodes."), - 'status': 'ok', - }) - messages.append(validate_roles(request, plan)) - messages.append(validate_global_parameters(request, plan)) - if not MATCHING_DEPLOYMENT_MODE: - # All roles have to have the same flavor. - default_flavor_name = api.flavor.Flavor.list(request)[0].name - for role in plan.role_list: - if role.flavor(plan).name != default_flavor_name: - messages.append({ - 'text': _(u"Role {0} doesn't use default flavor.").format( - role.name, - ), - 'is_critical': False, - 'statis': 'error', - }) - roles_assigned = True - messages.append({ - 'text': _(u"Assign roles."), - 'status': lambda: 'ok' if roles_assigned else 'pending', - }) - try: - controller_role = plan.get_role_by_name("Controller") - except KeyError: - messages.append({ - 'text': _(u"Controller Role Needed."), - 'is_critical': True, - 'status': 'error', - 'indent': 1, - }) - roles_assigned = False - else: - if plan.get_role_node_count(controller_role) not in (1, 3): - messages.append({ - 'text': _(u"1 or 3 Controllers Needed."), - 'is_critical': True, - 'status': 'pending', - 'indent': 1, - }) - roles_assigned = False - else: - messages.append({ - 'text': _(u"1 or 3 Controllers Needed."), - 'status': 'ok', - 'indent': 1, - }) - - try: - compute_role = plan.get_role_by_name("Compute") - except KeyError: - messages.append({ - 'text': _(u"Compute Role Needed."), - 'is_critical': True, - 'status': 'error', - 'indent': 1, - }) - roles_assigned = False - else: - if plan.get_role_node_count(compute_role) < 1: - messages.append({ - 'text': _(u"1 Compute Needed."), - 'is_critical': True, - 'status': 'pending', - 'indent': 1, - }) - roles_assigned = False - else: - messages.append({ - 'text': _(u"1 Compute Needed."), - 'status': 'ok', - 'indent': 1, - }) - for message in messages: - status = message.get('status') - if callable(status): - message['status'] = status = status() - message['classes'] = MESSAGE_ICONS.get(status, MESSAGE_ICONS[None]) - return messages - - -class EditPlan(horizon.forms.SelfHandlingForm): - def __init__(self, *args, **kwargs): - super(EditPlan, self).__init__(*args, **kwargs) - self.plan = api.tuskar.Plan.get_the_plan(self.request) - self.fields.update(self._role_count_fields(self.plan)) - - def _role_count_fields(self, plan): - fields = {} - for role in plan.role_list: - field = django.forms.IntegerField( - label=role.name, - widget=tuskar_ui.forms.NumberPickerInput(attrs={ - 'min': 1 if role.name in ('Controller', 'Compute') else 0, - 'step': 2 if role.name == 'Controller' else 1, - }), - initial=plan.get_role_node_count(role), - required=False - ) - field.role = role - fields['%s-count' % role.id] = field - return fields - - def handle(self, request, data): - parameters = dict( - (field.role.node_count_parameter_name, data[name]) - for (name, field) in self.fields.items() if name.endswith('-count') - ) - # NOTE(gfidente): this is a bad hack meant to magically add the - # parameter which enables Neutron L3 HA when the number of - # Controllers is > 1 - try: - controller_role = self.plan.get_role_by_name('Controller') - compute_role = self.plan.get_role_by_name('Compute') - except Exception as e: - LOG.warning('Unable to find a required role: %s', e.message) - else: - number_controllers = parameters[ - controller_role.node_count_parameter_name] - if number_controllers > 1: - for role in [controller_role, compute_role]: - l3ha_param = role.parameter_prefix + 'NeutronL3HA' - parameters[l3ha_param] = 'True' - l3agent_param = (role.parameter_prefix + - 'NeutronAllowL3AgentFailover') - parameters[l3agent_param] = 'True' - dhcp_agents_per_net = (number_controllers if number_controllers and - number_controllers > 3 else 3) - dhcp_agents_param = (controller_role.parameter_prefix + - 'NeutronDhcpAgentsPerNetwork') - parameters[dhcp_agents_param] = dhcp_agents_per_net - - try: - ceph_storage_role = self.plan.get_role_by_name('Ceph-Storage') - except Exception as e: - LOG.warning('Unable to find role: %s', 'Ceph-Storage') - else: - if parameters[ceph_storage_role.node_count_parameter_name] > 0: - parameters.update({ - 'CephClusterFSID': six.text_type(uuid.uuid4()), - 'CephMonKey': tuskar_utils.create_cephx_key(), - 'CephAdminKey': tuskar_utils.create_cephx_key() - }) - - cinder_enable_rbd_param = (controller_role.parameter_prefix - + 'CinderEnableRbdBackend') - glance_backend_param = (controller_role.parameter_prefix + - 'GlanceBackend') - nova_enable_rbd_param = (compute_role.parameter_prefix + - 'NovaEnableRbdBackend') - cinder_enable_iscsi_param = ( - controller_role.parameter_prefix + - 'CinderEnableIscsiBackend') - - parameters.update({ - cinder_enable_rbd_param: True, - glance_backend_param: 'rbd', - nova_enable_rbd_param: True, - cinder_enable_iscsi_param: False - }) - - try: - self.plan = self.plan.patch(request, self.plan.uuid, parameters) - except Exception as e: - horizon.exceptions.handle(request, _("Unable to update the plan.")) - LOG.exception(e) - return False - return True - - -class ScaleOut(EditPlan): - def __init__(self, *args, **kwargs): - super(ScaleOut, self).__init__(*args, **kwargs) - for name, field in self.fields.items(): - if name.endswith('-count'): - field.widget.attrs['min'] = field.initial - - def handle(self, request, data): - if not super(ScaleOut, self).handle(request, data): - return False - plan = self.plan - try: - stack = api.heat.Stack.get_by_plan(self.request, plan) - stack.update(request, plan.name, plan.templates) - except Exception as e: - LOG.exception(e) - if hasattr(e, 'error'): - horizon.exceptions.handle( - request, - _( - "Unable to deploy overcloud. Reason: {0}" - ).format(e.error['error']['message']), - ) - return False - else: - raise - else: - msg = _('Deployment in progress.') - horizon.messages.success(request, msg) - return True - - -class DeployOvercloud(horizon.forms.SelfHandlingForm): - network_isolation = horizon.forms.BooleanField( - label=_("Enable Network Isolation"), - required=False) - - def handle(self, request, data): - try: - plan = api.tuskar.Plan.get_the_plan(request) - except Exception as e: - LOG.exception(e) - horizon.exceptions.handle(request, - _("Unable to deploy overcloud.")) - return False - - # If network isolation selected, read environment file data - # and add to plan - env_temp = '/usr/share/openstack-tripleo-heat-templates/environments' - try: - if self.cleaned_data['network_isolation']: - with open(env_temp, 'r') as env_file: - env_contents = ''.join( - [line for line in - env_file.readlines() if '#' not in line] - ) - plan.environment += env_contents - except Exception as e: - LOG.exception(e) - pass - - # Auto-generate missing passwords and certificates - if plan.list_generated_parameters(): - generated_params = plan.make_generated_parameters() - plan = plan.patch(request, plan.uuid, generated_params) - - # Validate plan and create stack - for message in validate_plan(request, plan): - if message.get('is_critical'): - horizon.messages.success(request, message.text) - return False - try: - stack = api.heat.Stack.get_by_plan(self.request, plan) - if not stack: - api.heat.Stack.create(request, plan.name, plan.templates) - except Exception as e: - LOG.exception(e) - horizon.exceptions.handle( - request, _("Unable to deploy overcloud. Reason: {0}").format( - e.error['error']['message'])) - return False - else: - msg = _('Deployment in progress.') - horizon.messages.success(request, msg) - return True - - -class UndeployOvercloud(horizon.forms.SelfHandlingForm): - def handle(self, request, data): - try: - plan = api.tuskar.Plan.get_the_plan(request) - stack = api.heat.Stack.get_by_plan(self.request, plan) - if stack: - api.heat.Stack.delete(request, stack.id) - except Exception as e: - LOG.exception(e) - horizon.exceptions.handle(request, - _("Unable to undeploy overcloud.")) - return False - else: - msg = _('Undeployment in progress.') - horizon.messages.success(request, msg) - return True - - -class PostDeployInit(horizon.forms.SelfHandlingForm): - admin_email = horizon.forms.CharField(label=_("Admin Email")) - public_host = horizon.forms.CharField( - label=_("Public Host"), initial="", required=False) - region = horizon.forms.CharField( - label=_("Region"), initial="regionOne") - - def build_endpoints(self, plan, controller_role): - return { - "ceilometer": { - "password": plan.parameter_value( - controller_role.parameter_prefix + 'CeilometerPassword')}, - "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')}, - "glance": { - "password": plan.parameter_value( - controller_role.parameter_prefix + 'GlancePassword')}, - "heat": { - "password": plan.parameter_value( - controller_role.parameter_prefix + 'HeatPassword')}, - "neutron": { - "password": plan.parameter_value( - controller_role.parameter_prefix + 'NeutronPassword')}, - "nova": { - "password": plan.parameter_value( - controller_role.parameter_prefix + 'NovaPassword')}, - "novav3": { - "password": plan.parameter_value( - controller_role.parameter_prefix + 'NovaPassword')}, - "swift": { - "password": plan.parameter_value( - controller_role.parameter_prefix + 'SwiftPassword'), - 'path': '/v1/AUTH_%(tenant_id)s', - 'admin_path': '/v1'}, - "horizon": { - 'port': '80', - 'path': WEBROOT, - 'admin_path': '%sadmin' % WEBROOT}} - - def handle(self, request, data): - try: - plan = api.tuskar.Plan.get_the_plan(request) - controller_role = plan.get_role_by_name("Controller") - stack = api.heat.Stack.get_by_plan(self.request, plan) - - admin_token = plan.parameter_value( - controller_role.parameter_prefix + 'AdminToken') - admin_password = plan.parameter_value( - controller_role.parameter_prefix + 'AdminPassword') - admin_email = data['admin_email'] - auth_ip = stack.keystone_ip - auth_url = stack.keystone_auth_url - auth_tenant = 'admin' - auth_user = 'admin' - - # do the keystone init - keystone_config.initialize( - auth_ip, admin_token, admin_email, admin_password, - region='regionOne', ssl=None, public=None, user='heat-admin', - pki_setup=False) - - # retrieve needed Overcloud clients - keystone_client = clients.get_keystone_client( - auth_user, admin_password, auth_tenant, auth_url) - - # do the setup endpoints - keystone_config.setup_endpoints( - self.build_endpoints(plan, controller_role), - public_host=data['public_host'], - region=data['region'], - os_auth_url=auth_url, - client=keystone_client) - - except Exception as e: - LOG.exception(e) - horizon.exceptions.handle(request, - _("Unable to initialize Overcloud.")) - return False - else: - msg = _('Overcloud has been initialized.') - horizon.messages.success(request, msg) - return True |