def test_get_solum_plan(self): """Test the CAMP plans resource. Test that an plan resource created through the Solum API is visible via the CAMP API. """ if base.config_set_as('camp_enabled', False): self.skipTest('CAMP not enabled.') # create a plan using Solum p_resp = self.client.create_plan() self.assertEqual(201, p_resp.status) # get the CAMP plans resource resp, body = self.client.get('camp/v1_1/plans') self.assertEqual(200, resp.status, 'GET plans resource') plans_dct = json.loads(body) plan_links = plans_dct['plan_links'] self.assertEqual(1, len(plan_links)) p_link = plan_links[0] url = p_link['href'][len(self.client.base_url) + 1:] msg = ("GET Solum plan resource for %s" % p_link['target_name']) resp, body = self.client.get(url, headers={'content-type': 'application/x-yaml'}) self.assertEqual(200, resp.status, msg) # Solum plans are rendered in YAML plan = yamlutils.load(body) self.assertEqual(base.plan_sample_data['name'], plan['name']) self.assertEqual(base.plan_sample_data['description'], plan['description'])
def post(self, data): """Create a new app.""" request.check_request_for_https() if not data: raise exception.BadRequest(reason='No data.') self._validate(data) handler = app_handler.AppHandler(pecan.request.security_context) app_data = data.as_dict(app.App) try: raw_content = yamlutils.load(pecan.request.body) except ValueError: try: raw_content = json.loads(pecan.request.body) except ValueError as exp: LOG.exception(exp) raise exception.BadRequest(reason='Invalid app data.') app_data['raw_content'] = json.dumps(raw_content) new_app = handler.create(app_data) created_app = app.App.from_db_model(new_app, pecan.request.host_url) return created_app
def _get_context_from_last_execution(self, pipeline): last_execution = pipeline.last_execution() if last_execution is None: return osc = self._clients try: execution = osc.mistral().executions.get( pipeline.workbook_name, last_execution.uuid) execution_ctx = json.loads(execution.context) str_definition = osc.mistral().workbooks.get_definition( pipeline.workbook_name) definition = yamlutils.load(str_definition) except base.APIException: LOG.debug('Could not get last_execution(%s)' % last_execution, exc_info=True) return tasks = definition['Workflow'].get('tasks', {}) inputs = set() outputs = set() for act in tasks: inputs |= set(tasks[act].get('parameters', {}).keys()) outputs |= set(tasks[act].get('publish', {}).keys()) inputs -= outputs return dict((key, execution_ctx.get(key)) for key in inputs)
def _get_context_from_last_execution(self, pipeline): last_execution = pipeline.last_execution() if last_execution is None: return osc = self._clients try: execution = osc.mistral().executions.get(pipeline.workbook_name, last_execution.uuid) execution_ctx = json.loads(execution.context) str_definition = osc.mistral().workbooks.get_definition( pipeline.workbook_name) definition = yamlutils.load(str_definition) except base.APIException: LOG.debug('Could not get last_execution(%s)' % last_execution, exc_info=True) return tasks = definition['Workflow'].get('tasks', {}) inputs = set() outputs = set() for act in tasks: inputs |= set(tasks[act].get('parameters', {}).keys()) outputs |= set(tasks[act].get('publish', {}).keys()) inputs -= outputs return dict((key, execution_ctx.get(key)) for key in inputs)
def init_yml_plan_by_version(): try: yml_input_plan = yamlutils.load(pecan.request.body) except ValueError as excp: LOG.error("Invalid plan.") raise exception.BadRequest(reason='Plan is invalid. ' + six.text_type(excp)) return init_plan_by_version(yml_input_plan)
def init_yml_plan_by_version(): try: yml_input_plan = yamlutils.load(pecan.request.body) except ValueError as excp: LOG.error("Invalid plan.") raise exception.BadRequest(reason='Plan is invalid. ' + excp.message) return init_plan_by_version(yml_input_plan)
def post(self): """Create a new plan.""" if not pecan.request.body or len(pecan.request.body) < 1: raise exception.BadRequest try: yml_input_plan = yamlutils.load(pecan.request.body) except ValueError as excp: raise exception.BadRequest(reason='Plan is invalid. ' + excp.message) handler, data = init_plan_by_version(yml_input_plan) create_plan_yml = yamlutils.dump( yaml_content(handler.create(data.as_dict(objects.registry.Plan)))) pecan.response.status = 201 return create_plan_yml
def put(self): """Modify this plan.""" if not pecan.request.body or len(pecan.request.body) < 1: raise exception.BadRequest try: yml_input_plan = yamlutils.load(pecan.request.body) except ValueError as excp: raise exception.BadRequest(reason='Plan is invalid. ' + excp.message) handler, data = init_plan_by_version(yml_input_plan) updated_plan_yml = yamlutils.dump(yaml_content(handler.update( self._id, data.as_dict(objects.registry.Plan)))) pecan.response.status = 200 return updated_plan_yml
def process_result_value(self, value, dialect): if value is not None: value = yamlutils.load(value) return value
def test_load_empty_list(self): yml_dict = yamlutils.load('[]') self.assertEqual([], yml_dict)
def test_load_yaml(self): yml_dict = yamlutils.load('a: x\nb: y\n') self.assertEqual({'a': 'x', 'b': 'y'}, yml_dict)
def post(self): """Create a new CAMP-style plan.""" if not pecan.request.body or len(pecan.request.body) < 1: raise exception.BadRequest # check to make sure the request has the right Content-Type if (pecan.request.content_type is None or pecan.request.content_type != 'application/x-yaml'): raise exception.UnsupportedMediaType( name=pecan.request.content_type, method='POST') try: yaml_input_plan = yamlutils.load(pecan.request.body) except ValueError as excp: raise exception.BadRequest(reason='Plan is invalid. ' + six.text_type(excp)) camp_version = yaml_input_plan.get('camp_version') if camp_version is None: raise exception.BadRequest( reason='camp_version attribute is missing from submitted Plan') elif camp_version != 'CAMP 1.1': raise exception.BadRequest(reason=UNSUP_VER_ERR % camp_version) # Use Solum's handler as the point of commonality. We can do this # because Solum stores plans in the DB in their JSON form. handler = (plan_handler. PlanHandler(pecan.request.security_context)) model_plan = model.Plan(**yaml_input_plan) # Move any inline Service Specifications to the "services" section. # This avoids an issue where WSME can't properly handle multi-typed # attributes (e.g. 'fulfillment'). It also smoothes out the primary # difference between CAMP plans and Solum plans, namely that Solum # plans don't have inline Service Specifications. for art in model_plan.artifacts: if art.requirements != wsme.Unset: for req in art.requirements: if (req.fulfillment != wsme.Unset and isinstance(req.fulfillment, model.ServiceSpecification)): s_spec = req.fulfillment # if the inline service spec doesn't have an id # generate one if s_spec.id == wsme.Unset: s_spec.id = uuidutils.generate_uuid() # move the inline service spec to the 'services' # section if model_plan.services == wsme.Unset: model_plan.services = [s_spec] else: model_plan.services.append(s_spec) # set the fulfillment to the service spec id req.fulfillment = "id:%s" % s_spec.id db_obj = handler.create(clean_plan(wjson.tojson(model.Plan, model_plan))) plan_dict = fluff_plan(db_obj.refined_content(), db_obj.uuid) pecan.response.status = 201 pecan.response.location = plan_dict['uri'] return plan_dict