From 35bceb9efc2db5110fcdb6b6220ef3c611a3a972 Mon Sep 17 00:00:00 2001 From: Tamar Ben-Shachar Date: Fri, 19 Jun 2015 11:37:03 -0700 Subject: [PATCH] dcos-1733 validate app/group updates --- cli/dcoscli/data/marathon-group-schema.json | 3 ++ cli/dcoscli/marathon/main.py | 54 +++++++++++++++++++-- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/cli/dcoscli/data/marathon-group-schema.json b/cli/dcoscli/data/marathon-group-schema.json index 7043809..a8921ab 100644 --- a/cli/dcoscli/data/marathon-group-schema.json +++ b/cli/dcoscli/data/marathon-group-schema.json @@ -298,6 +298,9 @@ "id": { "$ref": "#/definitions/app/properties/id" }, + "version": { + "$ref": "#/definitions/app/properties/version" + }, "required": [ "id" ] diff --git a/cli/dcoscli/marathon/main.py b/cli/dcoscli/marathon/main.py index 343c266..3a7825a 100644 --- a/cli/dcoscli/marathon/main.py +++ b/cli/dcoscli/marathon/main.py @@ -494,9 +494,12 @@ def _group_update(group_id, properties, force): client = marathon.create_client() # Ensure that the group exists - client.get_group(group_id) + current_group = client.get_group(group_id) + + schema = _data_schema() + group_resource = _parse_properties(properties, schema) + _validate_update(current_group, group_resource, schema) - group_resource = _parse_properties(properties, _data_schema()) deployment = client.update_group(group_id, group_resource, force) emitter.publish('Created deployment {}'.format(deployment)) @@ -596,15 +599,58 @@ def _update(app_id, properties, force): client = marathon.create_client() # Ensure that the application exists - client.get_app(app_id) + current_app = client.get_app(app_id) + + schema = _app_schema() + app_resource = _parse_properties(properties, schema) + _validate_update(current_app, app_resource, schema) - app_resource = _parse_properties(properties, _app_schema()) deployment = client.update_app(app_id, app_resource, force) emitter.publish('Created deployment {}'.format(deployment)) return 0 +def _validate_update(current_resource, properties, schema): + """ + Validate resource ("app" or "group") update + + :param current_resource: Marathon app definition + :type current_resource: dict + :param properties: resource JSON + :type properties: dict + :param schema: JSON schema used to verify properties + :type schema: dict + :rtype: None + """ + updated_resource = _clean_up_resource_definition(current_resource.copy()) + updated_resource.update(properties) + + errs = util.validate_json(updated_resource, schema) + if errs: + raise DCOSException(util.list_to_err(errs)) + + +def _clean_up_resource_definition(properties): + """ + Remove task properties and nulls from resource definition + + :param properties: resource JSON + :type properties: dict + :returns: resource JSON + :rtype: dict + """ + clean_properties = {} + for k, v in properties.items(): + if v: + if k in ["apps", "groups"]: + clean_properties[k] = [_clean_up_resource_definition(v[0])] + elif not k.startswith("task"): + clean_properties[k] = v + + return clean_properties + + def _parse_properties(properties, schema): """ :param properties: JSON items in the form key=value