Browse Source

Add validation for nodes configs section

Add check for nodes configs section - it should be a dict.

Change-Id: Ie0114881aca4f62cfd50ff5358808765aa2924f8
changes/92/430192/5
Peter Razumovsky 3 years ago
committed by Andrey Pavlov
parent
commit
35b7e1f5a7
5 changed files with 82 additions and 15 deletions
  1. +2
    -3
      fuel_ccp/deploy.py
  2. +11
    -0
      fuel_ccp/tests/base.py
  3. +0
    -11
      fuel_ccp/tests/test_config.py
  4. +31
    -1
      fuel_ccp/tests/test_deploy.py
  5. +38
    -0
      fuel_ccp/validation/deploy.py

+ 2
- 3
fuel_ccp/deploy.py View File

@@ -390,10 +390,9 @@ def _create_exports_configmap(exports_map):

def _make_topology(nodes, roles, replicas):
failed = False
# TODO(sreshetniak): move it to validation
if not nodes:
LOG.error("Nodes section is not specified in configs")
if not deploy_validation.validate_nodes_section(nodes, CONF.configs):
failed = True
# TODO(sreshetniak): move it to validation
if not roles:
LOG.error("Roles section is not specified in configs")
failed = True


+ 11
- 0
fuel_ccp/tests/base.py View File

@@ -16,7 +16,9 @@
# under the License.

from oslotest import base
import six

from fuel_ccp.config import _yaml
from fuel_ccp.tests import conf_fixture


@@ -26,3 +28,12 @@ class TestCase(base.BaseTestCase):
def setUp(self):
super(TestCase, self).setUp()
self.conf = self.useFixture(conf_fixture.Config()).conf

def nested_dict_to_attrdict(self, d):
if isinstance(d, dict):
return _yaml.AttrDict({k: self.nested_dict_to_attrdict(v)
for k, v in six.iteritems(d)})
elif isinstance(d, list):
return list(map(self.nested_dict_to_attrdict, d))
else:
return d

+ 0
- 11
fuel_ccp/tests/test_config.py View File

@@ -1,22 +1,11 @@
import io
import jsonschema
import six

from fuel_ccp import config
from fuel_ccp.config import _yaml
from fuel_ccp.tests import base


def nested_dict_to_attrdict(d):
if isinstance(d, dict):
return _yaml.AttrDict({k: nested_dict_to_attrdict(v)
for k, v in six.iteritems(d)})
elif isinstance(d, list):
return list(map(nested_dict_to_attrdict, d))
else:
return d


class TestConfigSchema(base.TestCase):
def test_validate_config_schema(self):
schema = config.get_config_schema()


+ 31
- 1
fuel_ccp/tests/test_deploy.py View File

@@ -8,6 +8,7 @@ import yaml
from fuel_ccp.config import _yaml
from fuel_ccp import deploy
from fuel_ccp.tests import base
from fuel_ccp.validation import deploy as deploy_validation


class TestDeploy(base.TestCase):
@@ -396,7 +397,7 @@ class TestDeployMakeTopology(base.TestCase):
]
})

def test_make_empty_topology(self):
def test_make_topology_failed(self):
self.assertRaises(RuntimeError,
deploy._make_topology, _yaml.AttrDict(),
_yaml.AttrDict(), _yaml.AttrDict())
@@ -407,6 +408,35 @@ class TestDeployMakeTopology(base.TestCase):
deploy._make_topology,
_yaml.AttrDict({"spam": "eggs"}),
_yaml.AttrDict(), _yaml.AttrDict())
self.assertRaises(RuntimeError,
deploy._make_topology,
self.nested_dict_to_attrdict(
{"node1": {"configs": "because-cows"}}),
_yaml.AttrDict({"spam": "eggs"}), None)

def test_nodes_configs_has_new_var(self):
nodes = {
'node1': {
'configs': {
'heat': {
'stack_params': {
'converge_resources': 'True',
}
}
}
}
}
configs = {
'heat': {
'stack_params': {
'debug': True
}
}
}
nodes = self.nested_dict_to_attrdict(nodes)
configs = self.nested_dict_to_attrdict(configs)
self.assertFalse(deploy_validation.validate_nodes_section(nodes,
configs))

def test_make_topology_without_replicas(self):
nodes = _yaml.AttrDict({


+ 38
- 0
fuel_ccp/validation/deploy.py View File

@@ -1,6 +1,11 @@
import logging

from fuel_ccp.common import utils
from fuel_ccp.config import _yaml
from fuel_ccp import dependencies

LOG = logging.getLogger(__name__)


def validate_requested_components(components, components_map):
"""Validate requested components.
@@ -17,3 +22,36 @@ def validate_requested_components(components, components_map):
raise RuntimeError('Following components are also required for '
'successful deployment: '
'%s' % ' '.join(not_provided_components))


def validate_nodes_section(nodes, configs):
valid = True
if not nodes:
LOG.error("Nodes section is not specified in configs")
valid = False
else:
for name in nodes:
if 'configs' in nodes[name]:
if not isinstance(nodes[name]['configs'], _yaml.AttrDict):
LOG.error("Nodes configs should be a dict, found "
"%s" % type(nodes[name]['configs']))
valid = False
break
else:
valid = validate_nodes_config(nodes[name]['configs'],
configs)
if not valid:
break
return valid


def validate_nodes_config(node_config, global_config):
for k in node_config:
if k not in global_config:
LOG.error('Nodes configs cannot contain new variables, just '
'override existent')
return False
elif (isinstance(node_config[k], (dict, _yaml.AttrDict)) and
isinstance(global_config[k], (dict, _yaml.AttrDict))):
return validate_nodes_config(node_config[k], global_config[k])
return True

Loading…
Cancel
Save