Merge "Added validation for long hostnames"
This commit is contained in:
commit
4e3cb32475
@ -201,13 +201,10 @@ class DirectEngine(e.Engine):
|
||||
|
||||
return None
|
||||
|
||||
def _get_inst_name(self, cluster_name, ng_name, index):
|
||||
return ('%s-%s-%03d' % (cluster_name, ng_name, index)).lower()
|
||||
|
||||
def _run_instance(self, cluster, node_group, idx, aa_groups):
|
||||
"""Create instance using nova client and persist them into DB."""
|
||||
ctx = context.ctx()
|
||||
name = self._get_inst_name(cluster.name, node_group.name, idx)
|
||||
name = g.generate_instance_name(cluster.name, node_group.name, idx)
|
||||
|
||||
userdata = self._generate_user_data_script(node_group, name)
|
||||
|
||||
|
@ -21,6 +21,7 @@ from sahara import context
|
||||
import sahara.exceptions as ex
|
||||
import sahara.plugins.base as plugin_base
|
||||
import sahara.service.api as api
|
||||
from sahara.utils import general as g
|
||||
import sahara.utils.openstack.heat as heat
|
||||
import sahara.utils.openstack.keystone as keystone
|
||||
import sahara.utils.openstack.nova as nova
|
||||
@ -29,6 +30,8 @@ import sahara.utils.openstack.nova as nova
|
||||
CONF = cfg.CONF
|
||||
conductor = cond.API
|
||||
|
||||
MAX_HOSTNAME_LENGTH = 64
|
||||
|
||||
|
||||
def _get_plugin_configs(plugin_name, hadoop_version, scope=None):
|
||||
pl_confs = {}
|
||||
@ -192,6 +195,19 @@ def check_cluster_exists(id):
|
||||
" doesn't exist" % id)
|
||||
|
||||
|
||||
def check_cluster_hostnames_lengths(cluster_name, node_groups):
|
||||
for ng in node_groups:
|
||||
longest_hostname = g.generate_instance_name(cluster_name,
|
||||
ng['name'], ng['count'])
|
||||
longest_hostname += '.'
|
||||
longest_hostname += CONF.node_domain
|
||||
if len(longest_hostname) > MAX_HOSTNAME_LENGTH:
|
||||
raise ex.InvalidException(
|
||||
"Composite hostname %s in provisioned cluster exceeds "
|
||||
"maximum limit %s characters" % (longest_hostname,
|
||||
MAX_HOSTNAME_LENGTH))
|
||||
|
||||
|
||||
def check_keypair_exists(keypair):
|
||||
try:
|
||||
nova.client().keypairs.get(keypair)
|
||||
@ -218,13 +234,15 @@ def check_cluster_template_exists(cluster_template_id):
|
||||
" doesn't exist" % cluster_template_id)
|
||||
|
||||
|
||||
def check_node_groups_in_cluster_templates(plugin_name, hadoop_version,
|
||||
def check_node_groups_in_cluster_templates(cluster_name, plugin_name,
|
||||
hadoop_version,
|
||||
cluster_template_id):
|
||||
c_t = api.get_cluster_template(id=cluster_template_id)
|
||||
n_groups = c_t.to_wrapped_dict()['cluster_template']['node_groups']
|
||||
check_network_config(n_groups)
|
||||
for node_group in n_groups:
|
||||
check_node_group_basic_fields(plugin_name, hadoop_version, node_group)
|
||||
check_cluster_hostnames_lengths(cluster_name, n_groups)
|
||||
|
||||
## NodeGroup templates related checks
|
||||
|
||||
|
@ -55,7 +55,8 @@ def check_cluster_create(data, **kwargs):
|
||||
ct_id = data['cluster_template_id']
|
||||
b.check_cluster_template_exists(ct_id)
|
||||
if not data.get('node_groups'):
|
||||
b.check_node_groups_in_cluster_templates(data['plugin_name'],
|
||||
b.check_node_groups_in_cluster_templates(data['name'],
|
||||
data['plugin_name'],
|
||||
data['hadoop_version'],
|
||||
ct_id)
|
||||
|
||||
@ -80,6 +81,7 @@ def check_cluster_create(data, **kwargs):
|
||||
|
||||
if data.get('node_groups'):
|
||||
b.check_network_config(data['node_groups'])
|
||||
b.check_cluster_hostnames_lengths(data['name'], data['node_groups'])
|
||||
|
||||
neutron_net_id = _get_cluster_field(data, 'neutron_management_network')
|
||||
if neutron_net_id:
|
||||
|
@ -85,5 +85,6 @@ def check_cluster_scaling(data, cluster_id, **kwargs):
|
||||
|
||||
if data.get("add_node_groups"):
|
||||
b.check_add_node_groups(cluster, data['add_node_groups'])
|
||||
|
||||
b.check_network_config(data['add_node_groups'])
|
||||
b.check_cluster_hostnames_lengths(cluster.name,
|
||||
data['add_node_groups'])
|
||||
|
@ -208,6 +208,31 @@ class TestClusterCreateValidation(u.ValidationTestCase):
|
||||
"'neutron_management_network' field is not found")
|
||||
)
|
||||
|
||||
def test_cluster_create_v_long_instance_names(self):
|
||||
self._assert_create_object_validation(
|
||||
data={
|
||||
'name': "long-long-cluster-name",
|
||||
'plugin_name': "vanilla",
|
||||
'hadoop_version': "1.2.1",
|
||||
'default_image_id': '550e8400-e29b-41d4-a716-446655440000',
|
||||
'neutron_management_network': 'd9a3bebc-f788-4b81-'
|
||||
'9a93-aa048022c1ca',
|
||||
'node_groups': [
|
||||
{
|
||||
"name": "long-long-long-very-long-node-group-name",
|
||||
"node_processes": ["namenode"],
|
||||
"flavor_id": "42",
|
||||
"count": 100,
|
||||
}
|
||||
]
|
||||
},
|
||||
bad_req_i=(1, 'INVALID_REFERENCE',
|
||||
"Composite hostname long-long-cluster-name-long-long-"
|
||||
"long-very-long-node-group-name-100.novalocal "
|
||||
"in provisioned cluster exceeds maximum limit 64 "
|
||||
"characters")
|
||||
)
|
||||
|
||||
def test_cluster_create_v_cluster_configs(self):
|
||||
self._assert_cluster_configs_validation(True)
|
||||
|
||||
|
@ -137,6 +137,24 @@ class TestScalingValidation(unittest2.TestCase):
|
||||
"Cluster already has nodegroup "
|
||||
"with name 'ng'")
|
||||
|
||||
data = {
|
||||
'add_node_groups': [
|
||||
{
|
||||
'name': 'very-very-very-very-very-very-long-ng-name',
|
||||
'flavor_id': '42',
|
||||
'node_processes': ['namenode'],
|
||||
'count': 10
|
||||
},
|
||||
]
|
||||
}
|
||||
patchers = u.start_patch()
|
||||
self._assert_check_scaling(
|
||||
data=data, cluster=cluster, expected_message=
|
||||
"Composite hostname test-cluster-very-very-very-very-"
|
||||
"very-very-long-ng-name-010.novalocal in provisioned cluster "
|
||||
"exceeds maximum limit 64 characters")
|
||||
u.stop_patch(patchers)
|
||||
|
||||
def _assert_calls(self, mock, call_info):
|
||||
if not call_info:
|
||||
self.assertEqual(mock.call_count, 0)
|
||||
|
@ -1,31 +0,0 @@
|
||||
# Copyright (c) 2013 Mirantis Inc.
|
||||
#
|
||||
# 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 unittest2
|
||||
|
||||
from sahara.service import direct_engine as e
|
||||
|
||||
|
||||
class TestDirectEngine(unittest2.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = e.DirectEngine()
|
||||
super(TestDirectEngine, self).setUp()
|
||||
|
||||
def test_get_inst_name(self):
|
||||
inst_name = "cluster-worker-001"
|
||||
self.assertEqual(
|
||||
self.engine._get_inst_name("cluster", "worker", 1), inst_name)
|
||||
self.assertEqual(
|
||||
self.engine._get_inst_name("CLUSTER", "WORKER", 1), inst_name)
|
@ -18,7 +18,7 @@ import unittest2
|
||||
from sahara.utils import general
|
||||
|
||||
|
||||
class FindDictTest(unittest2.TestCase):
|
||||
class UtilsGeneralTest(unittest2.TestCase):
|
||||
def test_find_dict(self):
|
||||
iterable = [
|
||||
{
|
||||
@ -39,3 +39,10 @@ class FindDictTest(unittest2.TestCase):
|
||||
|
||||
self.assertEqual({"a": 1, "b": 2, "c": 3},
|
||||
general.find_dict(iterable, a=1, b=2))
|
||||
|
||||
def test_generate_instance_name(self):
|
||||
inst_name = "cluster-worker-001"
|
||||
self.assertEqual(
|
||||
general.generate_instance_name("cluster", "worker", 1), inst_name)
|
||||
self.assertEqual(
|
||||
general.generate_instance_name("CLUSTER", "WORKER", 1), inst_name)
|
||||
|
@ -100,3 +100,7 @@ def generate_etc_hosts(cluster):
|
||||
instance.hostname())
|
||||
|
||||
return hosts
|
||||
|
||||
|
||||
def generate_instance_name(cluster_name, node_group_name, index):
|
||||
return ("%s-%s-%03d" % (cluster_name, node_group_name, index)).lower()
|
||||
|
@ -22,6 +22,7 @@ from sahara import context
|
||||
from sahara import exceptions as ex
|
||||
from sahara.openstack.common import log as logging
|
||||
from sahara.utils import files as f
|
||||
from sahara.utils import general as g
|
||||
from sahara.utils.openstack import base
|
||||
|
||||
|
||||
@ -36,7 +37,7 @@ def client():
|
||||
|
||||
|
||||
def _get_inst_name(cluster_name, ng_name, index):
|
||||
return ('%s-%s-%03d' % (cluster_name, ng_name, (index + 1))).lower()
|
||||
return g.generate_instance_name(cluster_name, ng_name, index + 1)
|
||||
|
||||
|
||||
def _get_port_name(inst_name):
|
||||
|
Loading…
Reference in New Issue
Block a user