From 0d4c19a9389a933cf5b5e83173f97f8cd72b7f5e Mon Sep 17 00:00:00 2001 From: Michael Hwang Date: Thu, 14 Sep 2017 13:06:21 -0400 Subject: Merge in changes there were made since seeding * Fix DR config keys issue * Add data format generate command * Improve error messaging * Add in support for inputs otherwise known as "sourced at deployment" Change-Id: I9d97c30aeba587315d7fd1a18c38f71d8199d42b Issue-Id: DCAEGEN2-91 Signed-off-by: Michael Hwang --- dcae-cli/dcae_cli/util/discovery.py | 15 ++++++++-- dcae-cli/dcae_cli/util/dmaap.py | 5 ++-- dcae-cli/dcae_cli/util/inputs.py | 40 ++++++++++++++++++++++++++ dcae-cli/dcae_cli/util/run.py | 22 ++++++++++---- dcae-cli/dcae_cli/util/tests/test_discovery.py | 5 ++++ dcae-cli/dcae_cli/util/tests/test_inputs.py | 37 ++++++++++++++++++++++++ 6 files changed, 114 insertions(+), 10 deletions(-) create mode 100644 dcae-cli/dcae_cli/util/inputs.py create mode 100644 dcae-cli/dcae_cli/util/tests/test_inputs.py (limited to 'dcae-cli/dcae_cli/util') diff --git a/dcae-cli/dcae_cli/util/discovery.py b/dcae-cli/dcae_cli/util/discovery.py index f5a4b82..a75165e 100644 --- a/dcae-cli/dcae_cli/util/discovery.py +++ b/dcae-cli/dcae_cli/util/discovery.py @@ -498,10 +498,20 @@ def _group_config(config, config_key_map): return grouped_conf +def _apply_inputs(config, inputs_map): + """Update configuration with inputs + + This method updates the values of the configuration parameters using values + from the inputs map. + """ + config.update(inputs_map) + return config + + @contextlib.contextmanager def config_context(user, cname, cver, params, interface_map, instance_map, - config_key_map, dmaap_map={}, instance_prefix=None, host=consul_host, - always_cleanup=True, force_config=False): + config_key_map, dmaap_map={}, inputs_map={}, instance_prefix=None, + host=consul_host, always_cleanup=True, force_config=False): '''Convenience utility for creating configs and cleaning them up Args @@ -518,6 +528,7 @@ def config_context(user, cname, cver, params, interface_map, instance_map, user, cname, cver, params, interface_map, instance_map, dmaap_map, instance_prefix, force=force_config) + conf = _apply_inputs(conf, inputs_map) conf = _group_config(conf, config_key_map) push_config(conf_key, conf, rels_key, rels, dmaap_key, dmaap_map, host) diff --git a/dcae-cli/dcae_cli/util/dmaap.py b/dcae-cli/dcae_cli/util/dmaap.py index 0c89d6d..138e909 100644 --- a/dcae-cli/dcae_cli/util/dmaap.py +++ b/dcae-cli/dcae_cli/util/dmaap.py @@ -287,9 +287,10 @@ def validate_dmaap_map_entries(dmaap_map, mr_config_keys, dr_config_keys): logger.error("Please use the \"--dmaap-file\" option") return False + config_keys = dr_config_keys + mr_config_keys # Look for missing keys is_missing = lambda config_key: config_key not in dmaap_map - missing_keys = list(filter(is_missing, mr_config_keys)) + missing_keys = list(filter(is_missing, config_keys)) if missing_keys: logger.error("Missing config keys in dmaap json: {0}".format( @@ -298,7 +299,7 @@ def validate_dmaap_map_entries(dmaap_map, mr_config_keys, dr_config_keys): return False # Look for unexpected keys - is_unexpected = lambda config_key: config_key not in mr_config_keys + is_unexpected = lambda config_key: config_key not in config_keys unexpected_keys = list(filter(is_unexpected, dmaap_map.keys())) if unexpected_keys: diff --git a/dcae-cli/dcae_cli/util/inputs.py b/dcae-cli/dcae_cli/util/inputs.py new file mode 100644 index 0000000..4b212e2 --- /dev/null +++ b/dcae-cli/dcae_cli/util/inputs.py @@ -0,0 +1,40 @@ +# ============LICENSE_START======================================================= +# org.onap.dcae +# ================================================================================ +# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +""" +Functions for handling inputs +""" + +class InputsValidationError(RuntimeError): + pass + +def filter_entries(inputs_map, spec): + """Filter inputs entries that are not in the spec""" + param_names = [ p["name"] for p in spec["parameters"] \ + if "sourced_at_deployment" in p and p["sourced_at_deployment"] ] + + # Identify any missing parameters from inputs_map + missing = list(filter(lambda pn: pn not in inputs_map, param_names)) + + if missing: + raise InputsValidationError( + "Inputs map is missing keys: {0}".format(missing)) + + return { pn: inputs_map[pn] for pn in param_names } diff --git a/dcae-cli/dcae_cli/util/run.py b/dcae-cli/dcae_cli/util/run.py index 11bc429..67535fa 100644 --- a/dcae-cli/dcae_cli/util/run.py +++ b/dcae-cli/dcae_cli/util/run.py @@ -27,7 +27,7 @@ import six from functools import partial import click from dcae_cli.util import docker_util as du -from dcae_cli.util import dmaap +from dcae_cli.util import dmaap, inputs from dcae_cli.util.cdap_util import run_component as run_cdap_component from dcae_cli.util.exc import DcaeException from dcae_cli.util import discovery as dis @@ -124,7 +124,7 @@ def _verify_component(name, max_wait, consul_host): def run_component(user, cname, cver, catalog, additional_user, attached, force, - dmaap_map, external_ip=None): + dmaap_map, inputs_map, external_ip=None): '''Runs a component based on the component type Args @@ -134,6 +134,8 @@ def run_component(user, cname, cver, catalog, additional_user, attached, force, this flag is set to True. dmaap_map: (dict) config_key to message router or data router connections. Used as a manual way to make available this information for the component. + inputs_map: (dict) config_key to value that is intended to be provided at + deployment time as an input ''' cname, cver = catalog.verify_component(cname, cver) ctype = catalog.get_component_type(cname, cver) @@ -154,12 +156,13 @@ def run_component(user, cname, cver, catalog, additional_user, attached, force, spec = catalog.get_component_spec(cname, cver) config_key_map = build_config_keys_map(spec) + inputs_map = inputs.filter_entries(inputs_map, spec) dmaap_map = _update_delivery_urls(spec, profile.docker_host.split(":")[0], dmaap_map) with config_context(user, cname, cver, params, interface_map, - instance_map, config_key_map, dmaap_map=dmaap_map, + instance_map, config_key_map, dmaap_map=dmaap_map, inputs_map=inputs_map, always_cleanup=should_wait, force_config=force) as (instance_name, _): image = catalog.get_docker_image(cname, cver) docker_config = catalog.get_docker_config(cname, cver) @@ -201,17 +204,20 @@ def run_component(user, cname, cver, catalog, additional_user, attached, force, elif ctype =='cdap': (jar, config, spec) = catalog.get_cdap(cname, cver) config_key_map = build_config_keys_map(spec) + inputs_map = inputs.filter_entries(inputs_map, spec) + params, interface_map = catalog.get_discovery_for_cdap(cname, cver, neighbors) with config_context(user, cname, cver, params, interface_map, instance_map, - config_key_map, dmaap_map=dmaap_map, always_cleanup=False, + config_key_map, dmaap_map=dmaap_map, inputs_map=inputs_map, always_cleanup=False, force_config=force) as (instance_name, templated_conf): run_cdap_component(catalog, params, instance_name, profile, jar, config, spec, templated_conf) else: raise DcaeException("Unsupported component type for run") -def dev_component(user, catalog, specification, additional_user, force, dmaap_map): +def dev_component(user, catalog, specification, additional_user, force, dmaap_map, + inputs_map): '''Sets up the discovery layer for in development component The passed-in component specification is @@ -234,6 +240,8 @@ def dev_component(user, catalog, specification, additional_user, force, dmaap_ma this flag is set to True. dmaap_map: (dict) config_key to message router connections. Used as a manual way to make available this information for the component. + inputs_map: (dict) config_key to value that is intended to be provided at + deployment time as an input ''' instance_map = _get_instances(user, additional_user) neighbors = six.iterkeys(instance_map) @@ -247,11 +255,13 @@ def dev_component(user, catalog, specification, additional_user, force, dmaap_ma cname = specification["self"]["name"] cver = specification["self"]["version"] config_key_map = build_config_keys_map(specification) + inputs_map = inputs.filter_entries(inputs_map, specification) dmaap_map = _update_delivery_urls(specification, "localhost", dmaap_map) with config_context(user, cname, cver, params, interface_map, instance_map, - config_key_map, dmaap_map, always_cleanup=True, force_config=force) \ + config_key_map, dmaap_map, inputs_map=inputs_map, always_cleanup=True, + force_config=force) \ as (instance_name, templated_conf): click.echo("Ready for component development") diff --git a/dcae-cli/dcae_cli/util/tests/test_discovery.py b/dcae-cli/dcae_cli/util/tests/test_discovery.py index bf9205a..aed5ca8 100644 --- a/dcae-cli/dcae_cli/util/tests/test_discovery.py +++ b/dcae-cli/dcae_cli/util/tests/test_discovery.py @@ -443,6 +443,11 @@ def test_parse_instance_lookup(): assert dis.parse_instance_lookup(results) == "192.168.1.100:8080" +def test_apply_inputs(): + updated_config = dis._apply_inputs({"foo": "bar"}, {"foo": "baz"}) + assert updated_config == {"foo": "baz"} + + if __name__ == '__main__': '''Test area''' pytest.main([__file__, ]) diff --git a/dcae-cli/dcae_cli/util/tests/test_inputs.py b/dcae-cli/dcae_cli/util/tests/test_inputs.py new file mode 100644 index 0000000..5271705 --- /dev/null +++ b/dcae-cli/dcae_cli/util/tests/test_inputs.py @@ -0,0 +1,37 @@ +# ============LICENSE_START======================================================= +# org.onap.dcae +# ================================================================================ +# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +""" +Tests for inputs module +""" +import pytest +from dcae_cli.util import inputs + + +def test_filter_entries(): + spec = { "parameters": [{"name": "foo"}, {"name": "bar", + "sourced_at_deployment": False}, {"name": "baz", "sourced_at_deployment": True}] } + + with pytest.raises(inputs.InputsValidationError): + inputs.filter_entries({}, spec) + + inputs_map = { "foo": "do not copy", "baz": "hello world", "extra": "do not copy" } + + assert len(inputs.filter_entries(inputs_map, spec)) == 1 -- cgit 1.2.3-korg