def test_bad_service_name(self): content = self.read_bp('bad_service_name.bp') with self.assertRaises(blueprint.BadBlueprintFormatError) as cm: blueprint.parse(content) err = cm.exception self.assertEqual( err.args[1], "Service name should be digits or alphanumeric. you passed [node1$bad]" )
def test_bad_service_key(self): content = self.read_bp('bad_service_key.bp') with self.assertRaises(blueprint.BadBlueprintFormatError) as cm: blueprint.parse(content) err = cm.exception self.assertEqual( err.args[1], "Key for service creation is not right format, needs to be '$template__$instance', found:'node_node1'" )
def test_missing_actions(self): content = self.read_bp('missing_actions.bp') with self.assertRaises(blueprint.BadBlueprintFormatError) as cm: blueprint.parse(content) err = cm.exception self.assertNotEqual(err.args[0], "need to specify action key in action block") self.assertDictEqual( err.block, { 'actions': { 'template': 'github.com/threefoldtech/0-robot/node/0.0.1', 'service': 'node1' } })
def test_parse_with_args(self): content = self.read_bp('valid_with_args.bp') actions, services = blueprint.parse(content) self.assertEqual(len(actions), 1, 'number of actions should be 1') action = actions[0] self.assertEqual(action['template'], 'github.com/threefoldtech/0-robot/node/0.0.1') self.assertEqual(action['service'], 'node1') self.assertIn(action['action'], 'foo') self.assertDictEqual(action['args'], {'bar': 'hello', 'bor': 'world'})
def test_parse_blueprint(self): content = self.read_bp('valid.bp') actions, services = blueprint.parse(content) self.assertEqual(len(actions), 2, 'number of actions should be 2') for action in actions: self.assertEqual(action['template'], 'github.com/threefoldtech/0-robot/node/0.0.1') self.assertEqual(action['service'], 'node1') self.assertIn(action['action'], ['start', 'monitor']) self.assertEqual(len(services), 2) self.assertEqual(services[0]['template'], 'github.com/threefoldtech/0-robot/node/0.0.1') self.assertEqual(services[0]['service'], 'node1') self.assertDictEqual(services[0]['data'], {'foo': 'bar'})
def ExecuteBlueprintHandler(): """ Execute a blueprint on the ZeroRobot It is handler for POST /blueprints """ inputs = request.get_json() try: Blueprint_schema_validator.validate(inputs) except jsonschema.ValidationError as err: return jsonify(code=400, message=str(err)), 400 try: actions, services = blueprint.parse(inputs["content"]) except (blueprint.BadBlueprintFormatError, TemplateConflictError, TemplateNotFoundError) as err: return jsonify(code=400, message=str(err.args[1])), 400 services_created, err_code, err_msg = instantiate_services(services) if err_code or err_msg: return jsonify(code=err_code, message=err_msg), err_code services_2b_schedules = _find_services_to_be_scheduled(actions) allowed_services = auth.user_jwt.extract_service_guid(request) + [ s["guid"] for s in services_created ] not_allowed = set(services_2b_schedules) - set(allowed_services) if not_allowed: error_msg = "you are trying to schedule action on some services on which you don't have rights." return jsonify(code=401, message=error_msg), 401 tasks_created = [] for action_item in actions: try: tasks_created.extend(_schedule_action(action_item)) except BadActionArgumentError as err: err_msg = "bad action argument for action %s: %s" % ( action_item["action"], str(err)) return jsonify(code=400, message=err_msg), 400 response = {"tasks": [], "services": services_created} for task, service in tasks_created: response["tasks"].append(task_view(task, service)) return jsonify(response), 200