Merge "Designate integration"
This commit is contained in:
commit
51ff3a8eee
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
features:
|
||||
- Added integration with Designate for hostname resolution.
|
|
@ -9,6 +9,7 @@ Django<1.9,>=1.8 # BSD
|
|||
django-compressor>=2.0 # MIT
|
||||
django-openstack-auth>=2.3.0 # Apache-2.0
|
||||
iso8601>=0.1.11 # MIT
|
||||
python-designateclient>=1.5.0 # Apache-2.0
|
||||
python-keystoneclient!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
python-manilaclient>=1.10.0 # Apache-2.0
|
||||
python-neutronclient>=4.2.0 # Apache-2.0
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# 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 designateclient.v2 import client as designate
|
||||
from keystoneauth1.identity import generic
|
||||
from keystoneauth1 import session as keystone_session
|
||||
from openstack_dashboard.api import base
|
||||
|
||||
|
||||
def client(request):
|
||||
auth_url = base.url_for(request, 'identity')
|
||||
token_kwargs = dict(
|
||||
auth_url=auth_url,
|
||||
token=request.user.token.id,
|
||||
tenant_id=request.user.project_id,
|
||||
tenant_name=request.user.project_name,
|
||||
)
|
||||
auth = generic.Token(**token_kwargs)
|
||||
session = keystone_session.Session(auth=auth)
|
||||
return designate.Client(session=session)
|
||||
|
||||
|
||||
def get_domain_names(request):
|
||||
return client(request).zones.list()
|
|
@ -233,9 +233,9 @@ def nodegroup_update_acl_rules(request, nid,
|
|||
def cluster_template_create(request, name, plugin_name, hadoop_version,
|
||||
description=None, cluster_configs=None,
|
||||
node_groups=None, anti_affinity=None,
|
||||
net_id=None, use_autoconfig=None,
|
||||
shares=None,
|
||||
is_public=None, is_protected=None):
|
||||
net_id=None, use_autoconfig=None, shares=None,
|
||||
is_public=None, is_protected=None,
|
||||
domain_name=None):
|
||||
return client(request).cluster_templates.create(
|
||||
name=name,
|
||||
plugin_name=plugin_name,
|
||||
|
@ -248,7 +248,9 @@ def cluster_template_create(request, name, plugin_name, hadoop_version,
|
|||
use_autoconfig=use_autoconfig,
|
||||
shares=shares,
|
||||
is_public=is_public,
|
||||
is_protected=is_protected)
|
||||
is_protected=is_protected,
|
||||
domain_name=domain_name
|
||||
)
|
||||
|
||||
|
||||
def cluster_template_list(request, search_opts=None):
|
||||
|
@ -268,7 +270,8 @@ def cluster_template_update(request, ct_id, name, plugin_name,
|
|||
cluster_configs=None, node_groups=None,
|
||||
anti_affinity=None, net_id=None,
|
||||
use_autoconfig=None, shares=None,
|
||||
is_public=None, is_protected=None):
|
||||
is_public=None, is_protected=None,
|
||||
domain_name=None):
|
||||
try:
|
||||
template = client(request).cluster_templates.update(
|
||||
cluster_template_id=ct_id,
|
||||
|
@ -283,7 +286,8 @@ def cluster_template_update(request, ct_id, name, plugin_name,
|
|||
use_autoconfig=use_autoconfig,
|
||||
shares=shares,
|
||||
is_public=is_public,
|
||||
is_protected=is_protected
|
||||
is_protected=is_protected,
|
||||
domain_name=domain_name
|
||||
)
|
||||
|
||||
except APIException as e:
|
||||
|
|
|
@ -140,7 +140,8 @@ class DataProcessingClusterTemplateTests(test.TestCase):
|
|||
use_autoconfig=False,
|
||||
shares=ct.shares,
|
||||
is_public=False,
|
||||
is_protected=False) \
|
||||
is_protected=False,
|
||||
domain_name=ct.domain_name) \
|
||||
.AndReturn(new_ct)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
|
|
|
@ -102,6 +102,10 @@ class CopyClusterTemplate(create_flow.ConfigureClusterTemplate):
|
|||
fields['is_protected'].initial = (
|
||||
self.template.is_protected)
|
||||
|
||||
elif isinstance(step, create_flow.SelectDnsDomains):
|
||||
fields = step.action.fields
|
||||
fields["domain_name"].initial = self.template.domain_name
|
||||
|
||||
except Exception:
|
||||
exceptions.handle(request,
|
||||
_("Unable to fetch template to copy."))
|
||||
|
|
|
@ -21,6 +21,7 @@ from horizon import exceptions
|
|||
from horizon import forms
|
||||
from horizon import workflows
|
||||
|
||||
from sahara_dashboard.api import designate as designateclient
|
||||
from sahara_dashboard.api import manila as manilaclient
|
||||
from sahara_dashboard.api import sahara as saharaclient
|
||||
from sahara_dashboard.content.data_processing.utils import helpers as helpers
|
||||
|
@ -275,6 +276,40 @@ class SelectClusterShares(workflows.Step):
|
|||
return context
|
||||
|
||||
|
||||
class SelectDnsDomainsAction(workflows.Action):
|
||||
domain_name = forms.DynamicChoiceField(
|
||||
label=_("Domain Name"),
|
||||
required=False
|
||||
)
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(SelectDnsDomainsAction, self).__init__(request, *args, **kwargs)
|
||||
|
||||
def _get_domain_choices(self, request):
|
||||
domains = designateclient.get_domain_names(request)
|
||||
choices = [(None, _('No domain is specified'))]
|
||||
choices.extend(
|
||||
[(domain.get('name'), domain.get('name')) for domain in domains])
|
||||
return choices
|
||||
|
||||
def populate_domain_name_choices(self, request, context):
|
||||
return self._get_domain_choices(request)
|
||||
|
||||
class Meta(object):
|
||||
name = _("DNS Domain Names")
|
||||
help_text_template = (
|
||||
"cluster_templates/_config_domain_names_help.html")
|
||||
|
||||
|
||||
class SelectDnsDomains(workflows.Step):
|
||||
action_class = SelectDnsDomainsAction
|
||||
|
||||
def contribute(self, data, context):
|
||||
for k, v in data.items():
|
||||
context["dns_" + k] = v
|
||||
return context
|
||||
|
||||
|
||||
class ConfigureClusterTemplate(whelpers.ServiceParametersWorkflow,
|
||||
whelpers.StatusFormatMixin):
|
||||
slug = "configure_cluster_template"
|
||||
|
@ -303,6 +338,9 @@ class ConfigureClusterTemplate(whelpers.ServiceParametersWorkflow,
|
|||
if saharaclient.base.is_service_enabled(request, 'share'):
|
||||
ConfigureClusterTemplate._register_step(self, SelectClusterShares)
|
||||
|
||||
if saharaclient.base.is_service_enabled(request, 'dns'):
|
||||
ConfigureClusterTemplate._register_step(self, SelectDnsDomains)
|
||||
|
||||
self._populate_tabs(general_parameters, service_parameters)
|
||||
|
||||
super(ConfigureClusterTemplate, self).__init__(request,
|
||||
|
@ -353,6 +391,10 @@ class ConfigureClusterTemplate(whelpers.ServiceParametersWorkflow,
|
|||
if "ct_shares" in context:
|
||||
ct_shares = context["ct_shares"]
|
||||
|
||||
domain = context.get('dns_domain_name', None)
|
||||
if domain == 'None':
|
||||
domain = None
|
||||
|
||||
# TODO(nkonovalov): Fix client to support default_image_id
|
||||
saharaclient.cluster_template_create(
|
||||
request,
|
||||
|
@ -366,7 +408,8 @@ class ConfigureClusterTemplate(whelpers.ServiceParametersWorkflow,
|
|||
use_autoconfig=context['general_use_autoconfig'],
|
||||
shares=ct_shares,
|
||||
is_public=context['general_is_public'],
|
||||
is_protected=context['general_is_protected']
|
||||
is_protected=context['general_is_protected'],
|
||||
domain_name=domain
|
||||
)
|
||||
|
||||
hlps = helpers.Helpers(request)
|
||||
|
|
|
@ -48,6 +48,9 @@ class EditClusterTemplate(copy_flow.CopyClusterTemplate):
|
|||
fields["cluster_template_id"] = forms.CharField(
|
||||
widget=forms.HiddenInput(),
|
||||
initial=self.cluster_template_id)
|
||||
elif isinstance(step, create_flow.SelectDnsDomains):
|
||||
fields = step.action.fields
|
||||
fields["domain_name"].initial = self.template.domain_name
|
||||
except Exception:
|
||||
exceptions.handle(request,
|
||||
_("Unable to fetch template to edit."))
|
||||
|
@ -82,6 +85,10 @@ class EditClusterTemplate(copy_flow.CopyClusterTemplate):
|
|||
if "ct_shares" in context:
|
||||
ct_shares = context["ct_shares"]
|
||||
|
||||
domain = context.get('dns_domain_name', None)
|
||||
if domain == 'None':
|
||||
domain = None
|
||||
|
||||
saharaclient.cluster_template_update(
|
||||
request=request,
|
||||
ct_id=self.cluster_template_id,
|
||||
|
@ -95,7 +102,8 @@ class EditClusterTemplate(copy_flow.CopyClusterTemplate):
|
|||
use_autoconfig=context['general_use_autoconfig'],
|
||||
shares=ct_shares,
|
||||
is_public=context['general_is_public'],
|
||||
is_protected=context['general_is_protected']
|
||||
is_protected=context['general_is_protected'],
|
||||
domain_name=domain
|
||||
)
|
||||
return True
|
||||
except exceptions.Conflict as e:
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
{% load i18n horizon %}
|
||||
<div class="well">
|
||||
<p>
|
||||
{% blocktrans %}Select the domain name for internal and external hostname resolution.{% endblocktrans %}
|
||||
</p>
|
||||
<p>
|
||||
{% blocktrans %}Selected domain name should already exist in the Designate.
|
||||
You can check it in "DNS" tab on the left menu or by executing {% endblocktrans %}
|
||||
"designate domain-list"
|
||||
{% blocktrans %}on the controller node.{% endblocktrans %}
|
||||
</p>
|
||||
</div>
|
|
@ -22,6 +22,10 @@
|
|||
<dd>{{ template.is_public|yesno }}</dd>
|
||||
<dt>{% trans "Protected" %}</dt>
|
||||
<dd>{{ template.is_protected|yesno }}</dd>
|
||||
{% if template.domain_name %}
|
||||
<dt>{% trans "Domain name" %}</dt>
|
||||
<dd>{{ template.domain_name }}</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Anti-affinity enabled for" %}</dt>
|
||||
|
|
|
@ -215,7 +215,8 @@ def data(TEST):
|
|||
"shares": [],
|
||||
"plugin_name": "vanilla",
|
||||
"tenant_id": "429ad8447c2d47bc8e0382d244e1d1df",
|
||||
"updated_at": None
|
||||
"updated_at": None,
|
||||
"domain_name": None
|
||||
}
|
||||
|
||||
ct1 = cluster_templates.ClusterTemplate(
|
||||
|
|
Loading…
Reference in New Issue