New resources in API #516

Merged
merged 13 commits into from Apr 5, 2013

Projects

None yet

3 participants

@quamilek
Member
  • CIOwners resource in CMDB API
  • DeviceWithPricing resource - contain Device resource with pricing (per device component, splunk usage)
@ambv ambv commented on an outdated diff Apr 2, 2013
src/ralph/discovery/api.py
+class DeviceWithPricingResource(DeviceResource):
+ class Meta:
+ queryset = Device.objects.all()
+ resource_name = 'devicewithpricing'
+
+ def dehydrate(self, bundle):
+ device = bundle.obj
+ details = _get_details(bundle.obj)
+ components, stock = [], []
+ total = 0
+ for detail in details:
+ model = detail.get('model')
+ price = detail.get('price') or 0
+ model_type = None
+ try:
+ if isinstance(model, ComponentModel):
@ambv
ambv Apr 2, 2013

Isn't if model is not None: enough here?

@wmatyskiewicz wmatyskiewicz commented on an outdated diff Apr 4, 2013
+
+- **example returned data** ::
+
+ {
+ "meta": {
+ "limit": 1,
+ "next": "/api/v0.9/ciowners/?username=username&limit=2&format=json&api_key=api_key",
+ "offset": 0,
+ "previous": null,
+ "total_count": 175
+ },
+ "objects": [
+ {
+ "cache_version": 0,
+ "created": "2012-09-22T16:07:15",
+ "email": john.ralph@ralph.local,
@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
doc/api.rst
+- **link** ::
+
+ http://localhost:8000/api/v0.9/devicewithpricing/
+
+- HTTP Methods
+ * GET
+
+- **example returned data** ::
+
+ {
+ "meta": {
+ "limit": 1,
+ "next": "/api/v0.9/devicewithpricing/?username=ralph&api_key=ralph_pass&limit=1&offset=1&format=json",
+ "offset": 0,
+ "previous": null,
+ "total_count": 5408
@wmatyskiewicz
wmatyskiewicz Apr 4, 2013

Maybe good thing is add currency?
"currency": 'PLN'

@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
doc/api.rst
+ "offset": 0,
+ "previous": null,
+ "total_count": 5408
+ },
+ "objects": [
+ {
+ "barcode": "123456789",
+ "boot_firmware": null,
+ "cache_version": 21,
+ "cached_cost": 666.73,
+ "cached_price": 170.0725,
+ "chassis_position": 123456789,
+ "components": [
+ {
+ "count": 4,
+ "model": "CPU Quad-Core Xeon 2533MHz, 4-core",
@wmatyskiewicz
wmatyskiewicz Apr 4, 2013

api resource link?

@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
src/ralph/cmdb/api.py
expiration=EXPIRATION)
+
+class CIOwnersResource(MResource):
+ class Meta:
+ queryset = CIOwner.objects.all()
+ authentication = ApiKeyAuthentication()
+ authorization = DjangoAuthorization()
+ list_allowed_methods = ['get']
+ filtering = {
+ 'first_name': ('startswith', 'exact',),
+ 'last_name': ('startswith', 'exact',),
+ 'email': ('startswith', 'exact',),
@wmatyskiewicz
wmatyskiewicz Apr 4, 2013

add filtering with all of fields if not added

@wmatyskiewicz wmatyskiewicz commented on an outdated diff Apr 4, 2013
src/ralph/cmdb/tests/unit/tests_api.py
- 'new_value': self.cmdb_new_value,
- 'old_value': self.cmdb_old_value,
- 'time': '2012-11-15 12:00:00',
- })
- cmdb_resource = CIChangeCMDBHistoryResource()
- cmdb_resource.obj_create(bundle=cmdb_bundle)
+ self.post_data_cmdb_change = {
+ 'ci': '/api/v0.9/ci/%d/' % self.ci.pk,
+ 'comment': 'test api',
+ 'field_name': 'child',
+ 'new_value': self.cmdb_new_value,
+ 'old_value': self.cmdb_old_value,
+ 'time': '2012-11-15 12:00:00',
+ }
+
+ def create_user(self):
@wmatyskiewicz
wmatyskiewicz Apr 4, 2013

ralph.ui.test.global_utils -> login_as_su()

@wmatyskiewicz wmatyskiewicz commented on an outdated diff Apr 4, 2013
src/ralph/cmdb/tests/unit/tests_api.py
@@ -299,29 +306,25 @@ def test_ci_filter_startswith(self):
class CIApiTest(TestCase):
def setUp(self):
+ self.create_user()
@wmatyskiewicz
wmatyskiewicz Apr 4, 2013

ralph.ui.test.global_utils -> login_as_su()

@wmatyskiewicz wmatyskiewicz commented on an outdated diff Apr 4, 2013
src/ralph/discovery/api.py
+ class Meta:
+ queryset = Device.objects.all()
+ resource_name = 'devicewithpricing'
+
+ def dehydrate(self, bundle):
+ device = bundle.obj
+ details = _get_details(bundle.obj)
+ components = dict()
+ total = 0
+ for detail in details:
+ model = detail.get('model')
+ price = detail.get('price') or 0
+ model_type = None
+ model_name = str(model)
+ try:
+ if isinstance(model, ComponentModel):
@wmatyskiewicz
wmatyskiewicz Apr 4, 2013

remove except, check if ComponentModel has mode.type

@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
src/ralph/discovery/api.py
+ )
+ except ValueError:
+ pass
+ if model_type and model_type == ComponentType.software:
+ model = ComponentType.software.name,
+ model_name = model
+ if not components.get(model_name):
+ components[model_name] = {
+ 'model': model,
+ 'count': 1,
+ 'price': price,
+ 'serial': detail.get('serial'),
+ }
+ else:
+ components[model_name]['count'] += 1
+ total += price
@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
src/ralph/discovery/api.py
+ 'model': model,
+ 'count': 1,
+ 'price': price,
+ 'serial': detail.get('serial'),
+ }
+ else:
+ components[model_name]['count'] += 1
+ total += price
+ bundle.data['components'] = components.values()
+ bundle.data['total_cost'] = total
+ bundle.data['deprecated'] = device.is_deprecated()
+ splunk_start = bundle.request.GET.get('splunk_start')
+ splunk_end = bundle.request.GET.get('splunk_end')
+ if splunk_start and splunk_end:
+ try:
+ splunk_start = datetime.datetime.strptime(splunk_start, '%Y-%m-%d')
@wmatyskiewicz
wmatyskiewicz Apr 4, 2013

splunk_start = datetime.datetime.strptime(splunk_start, '%Y-%m-%d') if isinstance(splunk_start, datetime) else None

remove except

@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
src/ralph/discovery/api.py
+ 'count': 1,
+ 'price': price,
+ 'serial': detail.get('serial'),
+ }
+ else:
+ components[model_name]['count'] += 1
+ total += price
+ bundle.data['components'] = components.values()
+ bundle.data['total_cost'] = total
+ bundle.data['deprecated'] = device.is_deprecated()
+ splunk_start = bundle.request.GET.get('splunk_start')
+ splunk_end = bundle.request.GET.get('splunk_end')
+ if splunk_start and splunk_end:
+ try:
+ splunk_start = datetime.datetime.strptime(splunk_start, '%Y-%m-%d')
+ splunk_end = datetime.datetime.strptime(splunk_end, '%Y-%m-%d')
@wmatyskiewicz wmatyskiewicz commented on an outdated diff Apr 4, 2013
src/ralph/discovery/api.py
+ splunk = self.splunk_cost(bundle.obj, splunk_start, splunk_end)
+ bundle.data['splunk'] = splunk
+ return bundle
+
+ def splunk_cost(self, device, start_date=None, end_date=None):
+ splunk_cost = {
+ 'splunk_size': 0,
+ 'splunk_monthly_cost': 0,
+ 'splunk_daily_cost': 0,
+ }
+ if start_date and end_date:
+ splunk = device.splunkusage_set.filter(
+ day__range=(start_date, end_date)
+ ).order_by('-day')
+ else:
+ last_month = datetime.date.today() - datetime.timedelta(days=31)
@wmatyskiewicz
wmatyskiewicz Apr 4, 2013

teams determine : 30 days

@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
src/ralph/discovery/tests/test_api.py
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import datetime
+
+from django.contrib.auth.models import User
+from tastypie.test import ResourceTestCase
+
+from ralph.business.models import Venture
+from ralph.discovery.models import (
+ ComponentModel,
+ ComponentModelGroup,
+ ComponentType,
+ DeprecationKind,
+ DeviceType,
+ SplunkUsage
@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
src/ralph/discovery/tests/test_api.py
+)
+from ralph.ui.tests.util import create_device, create_model
+
+
+class DeviceWithPricingResourceTest(ResourceTestCase):
+ def setUp(self):
+ super(DeviceWithPricingResourceTest, self).setUp()
+
+ self.resource = 'devicewithpricing'
+ self.username = 'daniel'
+ self.password = 'pass'
+ self.user = User.objects.create_user(
+ 'ralph',
+ 'ralph@ralph.local',
+ 'ralph'
+ )
@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
src/ralph/discovery/tests/test_api.py
+ 'size': 512,
+ 'count': 6,
+ }
+ srv1_storage = {
+ 'model_name': 'Store 1TB',
+ 'label': 'store 1TB',
+ 'priority': 0,
+ 'family': 'Noname Store',
+ 'price': 180,
+ 'count': 10,
+ }
+ self.device = create_device(
+ device=srv1,
+ cpu=srv1_cpu,
+ memory=srv1_memory,
+ storage=srv1_storage
@wmatyskiewicz wmatyskiewicz commented on an outdated diff Apr 4, 2013
src/ralph/discovery/tests/test_api.py
+ type=ComponentType.unknown,
+ )
+ model.group = model_group
+ model.save()
+
+ res, created = SplunkUsage.concurrent_get_or_create(
+ device=self.device,
+ day=datetime.date.today(),
+ defaults={'model': model},
+ )
+ res.size = 10
+ res.save()
+
+ self.detail_url = '/api/v9/{0}/{1}/'.format(
+ self.resource,
+ self.device.pk
@wmatyskiewicz wmatyskiewicz commented on an outdated diff Apr 4, 2013
src/ralph/discovery/tests/test_api.py
+ res.size = 10
+ res.save()
+
+ self.detail_url = '/api/v9/{0}/{1}/'.format(
+ self.resource,
+ self.device.pk
+ )
+
+ def get_credentials(self):
+ return self.create_basic(username=self.username, password=self.password)
+
+ def test_get_list_json(self):
+ resp = self.api_client.get(
+ '/api/v0.9/{0}/'.format(self.resource),
+ format='json',
+ authentication=self.get_credentials()
@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
src/ralph/discovery/tests/test_api.py
+ authentication=self.get_credentials()
+ )
+ self.assertValidJSONResponse(resp)
+ device = self.deserialize(resp)['objects'][0]
+ self.assertEqual(device['id'], 1)
+ self.assertEqual(device['name'], 'Srv 1')
+ self.assertEqual(device['sn'], 'srv-1')
+ self.assertEqual(device['total_cost'], 2640)
+ self.assertDictEqual(
+ device['splunk'],
+ {
+ 'splunk_size': 10,
+ 'splunk_monthly_cost': 128.0,
+ 'splunk_daily_cost': 128.0
+ }
+ )
@wmatyskiewicz
wmatyskiewicz Apr 4, 2013

compare = {
device['id']: 1,
...
}

for key, item in compare.items():
self.assertEqual(key, item)

@wmatyskiewicz wmatyskiewicz commented on an outdated diff Apr 4, 2013
src/ralph/urls.py
@@ -12,13 +12,14 @@
from ralph.discovery.api import (IPAddressResource, ModelGroupResource,
ModelResource, PhysicalServerResource,
RackServerResource, VirtualServerResource,
- BladeServerResource, DevResource)
+ BladeServerResource, DevResource,
+ DeviceWithPricingResource)
@wmatyskiewicz
wmatyskiewicz Apr 4, 2013

all imports in new line

@wmatyskiewicz wmatyskiewicz commented on an outdated diff Apr 4, 2013
src/ralph/urls.py
from ralph.cmdb.api import (BusinessLineResource, ServiceResource,
CIRelationResource, CIResource, CIChangeResource,
CIChangeGitResource, CIChangePuppetResource,
CIChangeZabbixTriggerResource,
CIChangeCMDBHistoryResource, CILayersResource,
- CITypesResource)
+ CITypesResource, CIOwnersResource)
@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
src/ralph/urls.py
@@ -40,13 +41,14 @@
# discovery API
for r in (IPAddressResource, ModelGroupResource, ModelResource,
PhysicalServerResource, RackServerResource, BladeServerResource,
- VirtualServerResource, DevResource, WindowsDeviceResource):
+ VirtualServerResource, DevResource, WindowsDeviceResource,
+ DeviceWithPricingResource):
@wmatyskiewicz wmatyskiewicz commented on the diff Apr 4, 2013
src/ralph/urls.py
v09_api.register(r())
# CMDB API
for r in (BusinessLineResource, ServiceResource, CIResource,
CIRelationResource, CIChangeResource, CIChangeGitResource,
- CIChangePuppetResource, CIChangeZabbixTriggerResource,
+ CIOwnersResource, CIChangePuppetResource, CIChangeZabbixTriggerResource,
CIChangeCMDBHistoryResource, CITypesResource, CILayersResource):
@ambv ambv was assigned Apr 5, 2013
@ambv ambv merged commit f22862c into allegro:master Apr 5, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment