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/ChangeLog.md | 15 +++++ dcae-cli/dcae_cli/_version.py | 2 +- dcae-cli/dcae_cli/commands/component/commands.py | 48 ++++++++++++++-- dcae-cli/dcae_cli/commands/data_format/commands.py | 66 ++++++++++++++++++++++ .../commands/tests/mocked_components/model/badjson | 0 .../mocked_components/model/generatedir/ex1.json | 3 + .../mocked_components/model/generatedir/ex2.json | 4 ++ .../commands/tests/test_data_format_cmd.py | 35 ++++++++++++ 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 ++++++++++++ dcae-cli/requirements.txt | 3 +- dcae-cli/setup.py | 1 + 16 files changed, 284 insertions(+), 17 deletions(-) create mode 100644 dcae-cli/dcae_cli/commands/tests/mocked_components/model/badjson create mode 100755 dcae-cli/dcae_cli/commands/tests/mocked_components/model/generatedir/ex1.json create mode 100755 dcae-cli/dcae_cli/commands/tests/mocked_components/model/generatedir/ex2.json 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') diff --git a/dcae-cli/ChangeLog.md b/dcae-cli/ChangeLog.md index 249065b..4e169fc 100644 --- a/dcae-cli/ChangeLog.md +++ b/dcae-cli/ChangeLog.md @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [2.9.0] + +* Add data format generate command +* Fix issue with data router config keys + +## [2.8.1] + +* Improve error message when inputs map is missing item. Show the specific parameters that are causing issues. + +## [2.8.0] + +* Enhance to support parameters that are sourced at deployment +* Provide new command line arg --inputs-file +* Use inputs file to bind values to generated configuration for parameters that have been specified to be `sourced_at_deployment` true. + ## [2.7.0] * Rip out Docker related code and use common python-dockering library diff --git a/dcae-cli/dcae_cli/_version.py b/dcae-cli/dcae_cli/_version.py index 66bee2c..3f09935 100644 --- a/dcae-cli/dcae_cli/_version.py +++ b/dcae-cli/dcae_cli/_version.py @@ -19,4 +19,4 @@ # ECOMP is a trademark and service mark of AT&T Intellectual Property. # -*- coding: utf-8 -*- -__version__ = "2.7.0" +__version__ = "2.9.0" diff --git a/dcae-cli/dcae_cli/commands/component/commands.py b/dcae-cli/dcae_cli/commands/component/commands.py index 9c7a56d..4326636 100644 --- a/dcae-cli/dcae_cli/commands/component/commands.py +++ b/dcae-cli/dcae_cli/commands/component/commands.py @@ -29,7 +29,7 @@ import click from discovery_client import resolve_name -from dcae_cli.util import profiles, load_json, dmaap +from dcae_cli.util import profiles, load_json, dmaap, inputs from dcae_cli.util.run import run_component, dev_component from dcae_cli.util import discovery as dis from dcae_cli.util.discovery import DiscoveryNoDownstreamComponentError @@ -165,6 +165,28 @@ def _parse_dmaap_file(dmaap_file): message = "Problems with parsing the dmaap file. Check to make sure that it is a valid json and is in the expected structure." raise DcaeException(message) +_help_inputs_file = """ +Path to a file that contains a json that contains values to be used to bind to configuration parameters that have been marked as "sourced_at_deployment". The structure of the json is expected to be: + + { + : value, + : value + } + +The "parameter name" is the value of the "name" property for the given configuration parameter. +""" + +def _parse_inputs_file(inputs_file): + try: + with open(inputs_file, 'r+') as f: + inputs_map = json.load(f) + # TODO: Validation of schema in the future? Skipping this because + # dti_payload is not being intended to be used. + return inputs_map + except Exception as e: + message = "Problems with parsing the inputs file. Check to make sure that it is a valid json and is in the expected structure." + raise DcaeException(message) + @component.command() @click.option('--external-ip', '-ip', default=None, help='The external IP address of the Docker host. Only used for Docker components.') @@ -173,21 +195,29 @@ def _parse_dmaap_file(dmaap_file): @click.option('--force', is_flag=True, help='Force component to run without valid downstream dependencies') @click.option('--dmaap-file', type=click.Path(resolve_path=True, exists=True, dir_okay=False), help=_help_dmaap_file) +@click.option('--inputs-file', type=click.Path(resolve_path=True, exists=True, dir_okay=False), + help=_help_inputs_file) @click.argument('component') @click.pass_obj -def run(obj, external_ip, additional_user, attached, force, dmaap_file, component): +def run(obj, external_ip, additional_user, attached, force, dmaap_file, component, + inputs_file): '''Runs the latest version of COMPONENT. You may optionally specify version via COMPONENT:VERSION''' cname, cver = parse_input(component) user, catalog = obj['config']['user'], obj['catalog'] dmaap_map = _parse_dmaap_file(dmaap_file) if dmaap_file else {} + inputs_map = _parse_inputs_file(inputs_file) if inputs_file else {} try: run_component(user, cname, cver, catalog, additional_user, attached, force, - dmaap_map, external_ip) + dmaap_map, inputs_map, external_ip) except DiscoveryNoDownstreamComponentError as e: message = "Either run a compatible downstream component first or run with the --force flag to ignore this error" raise DcaeException(message) + except inputs.InputsValidationError as e: + click.echo("There is a problem. {0}".format(e)) + message = "Component requires inputs. Please look at the use of --inputs-file and make sure the format is correct" + raise DcaeException(message) @component.command() @click.argument('component') @@ -205,20 +235,28 @@ def undeploy(obj, component): @click.option('--force', is_flag=True, help='Force component to run without valid downstream dependencies') @click.option('--dmaap-file', type=click.Path(resolve_path=True, exists=True, dir_okay=False), help=_help_dmaap_file) +@click.option('--inputs-file', type=click.Path(resolve_path=True, exists=True, dir_okay=False), + help=_help_inputs_file) @click.pass_obj -def dev(obj, specification, additional_user, force, dmaap_file): +def dev(obj, specification, additional_user, force, dmaap_file, inputs_file): '''Set up component in development for discovery, use for local development''' user, catalog = obj['config']['user'], obj['catalog'] dmaap_map = _parse_dmaap_file(dmaap_file) if dmaap_file else {} + inputs_map = _parse_inputs_file(inputs_file) if inputs_file else {} with open(specification, 'r+') as f: spec = json.loads(f.read()) try: - dev_component(user, catalog, spec, additional_user, force, dmaap_map) + dev_component(user, catalog, spec, additional_user, force, dmaap_map, + inputs_map) except DiscoveryNoDownstreamComponentError as e: message = "Either run a compatible downstream component first or run with the --force flag to ignore this error" raise DcaeException(message) + except inputs.InputsValidationError as e: + click.echo("There is a problem. {0}".format(e)) + message = "Component requires inputs. Please look at the use of --inputs-file and make sure the format is correct" + raise DcaeException(message) @component.command() diff --git a/dcae-cli/dcae_cli/commands/data_format/commands.py b/dcae-cli/dcae_cli/commands/data_format/commands.py index 9114688..b942442 100644 --- a/dcae-cli/dcae_cli/commands/data_format/commands.py +++ b/dcae-cli/dcae_cli/commands/data_format/commands.py @@ -26,12 +26,22 @@ import json import click +import genson + +import sys + +import os + +from jsonschema import Draft4Validator + from dcae_cli.util import load_json from dcae_cli.util.logger import get_logger + from dcae_cli.commands import util from dcae_cli.commands.util import create_table, parse_input from dcae_cli.catalog.exc import MissingEntry +from dcae_cli.catalog.exc import DcaeException logger = get_logger('DataFormatCommand') @@ -96,3 +106,59 @@ def publish(obj, data_format): click.echo("Data format has been published") else: click.echo("Data format could not be published") + +@data_format.command() +@click.option('--keywords', is_flag=True, help='Adds a template of possible descriptive keywords', default=False) +@click.argument('name_version', metavar="name:version", required = True) +@click.argument('file-or-dir-path', type=click.Path(resolve_path=True, exists=True, dir_okay=True, file_okay=True, readable=True), metavar="file-or-dir-path") +@click.pass_obj +def generate(obj, name_version, file_or_dir_path, keywords): + '''Create schema from a file or directory examples''' + name, version = parse_input(name_version) + if version == None: + version = "" + schema = genson.Schema() + if os.path.isfile(file_or_dir_path): + addfile(file_or_dir_path, schema) + else: + foundJSON = False + for root, dirs, files in os.walk(file_or_dir_path): + for filename in files: + fullfilename = os.path.join(file_or_dir_path, filename) + addfile(fullfilename,schema) + foundJSON = True + if foundJSON == False: + raise DcaeException('No JSON files found in ' + file_or_dir_path) + + json_obj = json.loads(schema.to_json()) + json_obj['$schema'] = "http://json-schema.org/draft-04/schema#" + jschema = json.dumps(json_obj) + jschema = jschema.replace('"required":', '"additionalproperties": true, "required":') + jschema = jschema.replace('"type":', ' "description": "", "type":') + + if (keywords): + jschema = jschema.replace('"type": "string"', ' "maxLength": 0, "minLength": 0, "pattern": "", "type": "string"') + jschema = jschema.replace('"type": "integer"', ' "maximum": 0, "mininimum": 0, "multipleOf": 0, "type": "integer"') + jschema = jschema.replace('"type": "array"', ' "maxItems": 0, "minItems": 0, "uniqueItems": "false", "type": "array"') + + jschema = '{ "self": { "name": "' + name + '", "version": "' + version + '", "description": ""} , "dataformatversion": "1.0.0", "jsonschema": ' + jschema + '}' + #Draft4Validator.check_schema(json.loads(jschema)) + try: + print(json.dumps(json.loads(jschema), sort_keys=True, indent=4 )) + except ValueError: + raise DcaeException('Problem with JSON generation') + +def addfile(filename, schema): + try: + fileadd = open(filename, "r") + except IOError: + raise DcaeException('Cannot open' + filename) + try: + json_object = json.loads(fileadd.read()) + schema.add_object(json_object) + except ValueError: + raise DcaeException('Bad JSON file: ' + filename) + finally: + fileadd.close() + + diff --git a/dcae-cli/dcae_cli/commands/tests/mocked_components/model/badjson b/dcae-cli/dcae_cli/commands/tests/mocked_components/model/badjson new file mode 100644 index 0000000..e69de29 diff --git a/dcae-cli/dcae_cli/commands/tests/mocked_components/model/generatedir/ex1.json b/dcae-cli/dcae_cli/commands/tests/mocked_components/model/generatedir/ex1.json new file mode 100755 index 0000000..7db1e06 --- /dev/null +++ b/dcae-cli/dcae_cli/commands/tests/mocked_components/model/generatedir/ex1.json @@ -0,0 +1,3 @@ +{ + "foobar": "test 1" +} diff --git a/dcae-cli/dcae_cli/commands/tests/mocked_components/model/generatedir/ex2.json b/dcae-cli/dcae_cli/commands/tests/mocked_components/model/generatedir/ex2.json new file mode 100755 index 0000000..75a5fa4 --- /dev/null +++ b/dcae-cli/dcae_cli/commands/tests/mocked_components/model/generatedir/ex2.json @@ -0,0 +1,4 @@ +{ + "foobar2": "test 1" +} + diff --git a/dcae-cli/dcae_cli/commands/tests/test_data_format_cmd.py b/dcae-cli/dcae_cli/commands/tests/test_data_format_cmd.py index 754e6a7..b8402f6 100644 --- a/dcae-cli/dcae_cli/commands/tests/test_data_format_cmd.py +++ b/dcae-cli/dcae_cli/commands/tests/test_data_format_cmd.py @@ -77,6 +77,41 @@ def test_basic(): spec_str = runner.invoke(cli, cmd, obj=obj).output assert df_spec == json.loads(spec_str) + # test of generate + bad_dir = os.path.join(TEST_DIR, 'mocked_components', 'model', 'baddir') + cmd = "data_format generate --keywords \"name:1.0.2\" {:}".format(bad_dir).split() + err_str = runner.invoke(cli, cmd, obj=obj).output + assert "does not exist" in err_str + + empty_dir = os.path.join(TEST_DIR, 'mocked_components', 'model', 'emptydir') + try: + os.stat(empty_dir) + except: + os.mkdir(empty_dir) + cmd = "data_format generate --keywords \"name:1.0.2\" {:}".format(empty_dir).split() + err_str = runner.invoke(cli, cmd, obj=obj).output + assert "No JSON files found" in err_str + + bad_json = os.path.join(TEST_DIR, 'mocked_components', 'model', 'badjson') + cmd = "data_format generate --keywords \"name:1.0.2\" {:}".format(bad_json).split() + err_str = runner.invoke(cli, cmd, obj=obj).output + assert "Bad JSON file" in err_str + + generate_dir = os.path.join(TEST_DIR, 'mocked_components', 'model', 'generatedir') + cmd = "data_format generate --keywords name:1.0.2 {:} ".format(generate_dir).split() + out_str = runner.invoke(cli, cmd, obj=obj).output + assert '{\n "dataformatversion": "1.0.0", \n "jsonschema": {\n "$schema": "http://json-schema.org/draft-04/schema#", \n "description": "", \n "properties": {\n "foobar": {\n "description": "", \n "maxLength": 0, \n "minLength": 0, \n "pattern": "", \n "type": "string"\n }, \n "foobar2": {\n "description": "", \n "maxLength": 0, \n "minLength": 0, \n "pattern": "", \n "type": "string"\n }\n }, \n "type": "object"\n }, \n "self": {\n "description": "", \n "name": "name", \n "version": "1.0.2"\n }\n}\n' == out_str + + generate_dir = os.path.join(TEST_DIR, 'mocked_components', 'model', 'generatedir') + cmd = "data_format generate name:1.0.2 {:} ".format(generate_dir).split() + out_str = runner.invoke(cli, cmd, obj=obj).output + assert '{\n "dataformatversion": "1.0.0", \n "jsonschema": {\n "$schema": "http://json-schema.org/draft-04/schema#", \n "description": "", \n "properties": {\n "foobar": {\n "description": "", \n "type": "string"\n }, \n "foobar2": {\n "description": "", \n "type": "string"\n }\n }, \n "type": "object"\n }, \n "self": {\n "description": "", \n "name": "name", \n "version": "1.0.2"\n }\n}\n' == out_str + + generate_dir = os.path.join(TEST_DIR, 'mocked_components', 'model', 'generatedir', 'ex1.json') + cmd = "data_format generate name:1.0.2 {:} ".format(generate_dir).split() + out_str = runner.invoke(cli, cmd, obj=obj).output + assert '{\n "dataformatversion": "1.0.0", \n "jsonschema": {\n "$schema": "http://json-schema.org/draft-04/schema#", \n "additionalproperties": true, \n "description": "", \n "properties": {\n "foobar": {\n "description": "", \n "type": "string"\n }\n }, \n "required": [\n "foobar"\n ], \n "type": "object"\n }, \n "self": {\n "description": "", \n "name": "name", \n "version": "1.0.2"\n }\n}\n' == out_str + if __name__ == '__main__': '''Test area''' 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 diff --git a/dcae-cli/requirements.txt b/dcae-cli/requirements.txt index 63dce5e..52d5aa1 100644 --- a/dcae-cli/requirements.txt +++ b/dcae-cli/requirements.txt @@ -9,5 +9,6 @@ jsonschema==2.5.1 docker-py==1.10.6 terminaltables==3.1.0 python-discovery-client==2.0.0 -python-dockering==1.2.0 +python-dockering==1.2.1 psycopg2==2.7.1 +genson==0.2.2 diff --git a/dcae-cli/setup.py b/dcae-cli/setup.py index 25c4c4c..8c6405c 100644 --- a/dcae-cli/setup.py +++ b/dcae-cli/setup.py @@ -51,6 +51,7 @@ setup( 'docker-py>=1.10,<2', 'terminaltables', 'psycopg2', + 'genson', 'python-discovery-client>=2.0.0', 'python-dockering>=1.0.0,<2.0.0' ], -- cgit 1.2.3-korg