def test_bag(self): bag = DataBag.objects.create(name='mybag') data = {'id': 'item1', 'attr': 1, 'nested': {'nested_attr': 'foo'}} bag.items.create(name='item1', data=json.dumps(data)) data = {'id': 'item2', 'attr': 1, 'nested': {'nested_attr': 'bar'}} bag.items.create(name='item2', data=json.dumps(data)) data = {'id': 'item3', 'attr2': 1} bag.items.create(name='item3', data=json.dumps(data)) chef_query = chef.Search('mybag', 'attr:1') self.assertEqual(len(chef_query), 2) self.assertIn('item1', chef_query) self.assertIn('item2', chef_query)
def from_dict(self, data): chef_role = chef.Role.from_search(data) role, created = self.get_or_create(name=chef_role.name) role.description = chef_role.description role.override_data = json.dumps(chef_role.override_attributes) role.default_data = json.dumps(chef_role.default_attributes) role.save() role.run_list.all().delete() for entry in chef_role.run_list: if '[' not in entry: continue # Can't parse this type, name = entry.split('[', 1) name = name.rstrip(']') role.run_list.create(type=type, name=name) return role
def from_dict(self, data): chef_node = chef.Node.from_search(data) node, created = self.get_or_create(name=chef_node.name) node.automatic_data = json.dumps(chef_node.automatic) node.override_data = json.dumps(chef_node.override) node.normal_data = json.dumps(chef_node.normal) node.default_data = json.dumps(chef_node.default) node.save() node.run_list.all().delete() for entry in chef_node.run_list: if '[' not in entry: continue # Can't parse this type, name = entry.split('[', 1) name = name.rstrip(']') node.run_list.create(type=type, name=name) return node
def test_update(self): bag = DataBag.objects.create(name='mybag') data = {'id': 'myitem', 'attr': 1, 'nested': {'nested_attr': 'foo'}} bag.items.create(name='myitem', data=json.dumps(data)) chef_item = chef.DataBagItem('mybag', 'myitem') chef_item['attr'] = 2 chef_item['nested']['nested_attr'] = 'bar' chef_item.save() data2 = {'id': 'myitem', 'attr': 2, 'nested': {'nested_attr': 'bar'}} item = DataBagItem.objects.get(bag__name='mybag', name='myitem') self.assertEqual(json.loads(item.data), data2)
def item_update(self, request, bag_name, name): if not request.json: raise ChefAPIError(500, 'No data sent') data = request.json.get('raw_data') if not isinstance(data, dict): data = request.json if not isinstance(data, dict) or data.get('id') != name: raise ChefAPIError(500, 'Name mismatch in data bag item') item = self.get_item_or_404(bag_name, name) update(item, data=json.dumps(data)) return HttpResponse(item.data, status=200, content_type='application/json')
def execute_request(view, request, *args, **kwargs): if view is None: return create_error('No method found', 404) try: client = verify_request(request) decode_json(request) request.client = client data = view(request, *args, **kwargs) if not isinstance(data, HttpResponse): data = HttpResponse(json.dumps(data), content_type='application/json') return data except ChefAPIError, e: return create_error(e.msg, e.code)
def __call__(self, request, *args, **kwargs): view = self.dispatch_view.view_map.get(request.method) if view is None: return create_error('No method found', 404) try: client = verify_request(request) if view._commis_api['admin'] and not client.admin: raise ChefAPIError(403, 'You are not allowed to take this action') decode_json(request) request.client = client data = view(self.instance, request, *args, **kwargs) if not isinstance(data, HttpResponse): data = HttpResponse(json.dumps(data), content_type='application/json') return data except ChefAPIError, e: return create_error(e.msg, e.code)
def process_response(self, request, response): # We're primarily interested in debuggin API output. # Non-API URLs are typically hit by a user who will see the debug info # in the browser. API can't do that! if request.path.startswith("/api"): content = response.content # JSON responses (caveat: this is probably all of them...) should # get pretty-printed if response['content-type'] == 'application/json': obj = json.loads(content) # And responses containing a top level traceback key should # also pretty-print that value. traceback = obj and obj.pop('traceback', None) if traceback is not None: logger.debug(traceback) content = json.dumps(obj, indent=4) logger.debug(content) return response
def create_error(msg, code): return HttpResponse(json.dumps({'error': msg, 'traceback': traceback.format_exc()}), status=code, content_type='application/json')
def create(self, request): if self.model.objects.filter(name=request.json['name']).exists(): raise ChefAPIError(409, '%s %s already exists', self.model._meta.verbose_name, request.json['name']) obj = self.model.objects.from_dict(request.json) data = self.create_data(request, obj) return HttpResponse(json.dumps(data), status=201, content_type='application/json')
def test_get(self): bag = DataBag.objects.create(name='mybag') data = {'id': 'myitem', 'attr': 1, 'nested': {'nested_attr': 'foo'}} bag.items.create(name='myitem', data=json.dumps(data)) chef_item = chef.DataBagItem('mybag', 'myitem') self.assertEqual(data, chef_item)