valence/valence/db/models.py
Nate Potter 78da85116a Implement flavors
This patch implements flavors, allowing users to save composition
requirements to the database to be used at any time. Parameters
included are the flavor's name, RAM, number of CPU cores, and
processor model.

Change-Id: I356ca9162559598bf1415d2c3b151596f111ac0c
Implements: blueprint flavor
2017-01-25 16:13:55 -08:00

192 lines
5.4 KiB
Python

# copyright (c) 2016 Intel, Inc.
#
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import datetime
import json
import os
import etcd
from valence.common import base
from valence.common import types
from valence import db
class ModelBase(base.ObjectBase):
@classmethod
def etcd_path(cls, sub_path):
return os.path.normpath("/".join([cls.path, sub_path]))
def path_already_exist(self, client, path):
try:
client.read(path)
except etcd.EtcdKeyNotFound:
return False
return True
def save(self, client=None):
if not client:
client = db.etcd_driver.get_driver().client
path = self.etcd_path(self.uuid)
if self.path_already_exist(client, path):
# TODO(lin.a.yang): after exception module got merged, raise
# valence specific DBResouceConflict exception here
raise Exception(
'Database resource conflict on {0}.'.format(path))
client.write(path, json.dumps(self.as_dict()))
def update(self, values, client=None):
super(ModelBase, self).update(values)
if not client:
client = db.etcd_driver.get_driver().client
path = self.etcd_path(self.uuid)
if not self.path_already_exist(client, path):
# TODO(lin.a.yang): after exception module got merged, raise
# valence specific DBNotFound exception here
raise Exception(
'Database resource not found: {0}.'.format(path))
client.write(path, json.dumps(self.as_dict()))
def delete(self, client=None):
if not client:
client = db.etcd_driver.get_driver().client
path = self.etcd_path(self.uuid)
if not self.path_already_exist(client, path):
# TODO(lin.a.yang): after exception module got merged, raise
# valence specific DBNotFound exception here
raise Exception(
'Database resource not found: {0}.'.format(path))
client.delete(path)
class ModelBaseWithTimeStamp(ModelBase):
def __init__(self, *args, **kwargs):
"""Inject 'created_at' and 'updated_at' fields"""
timestamp_fields = {
'created_at': {
'validate': types.Text.validate
},
'updated_at': {
'validate': types.Text.validate
}
}
self.fields.update(timestamp_fields)
super(ModelBaseWithTimeStamp, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
"""Update all timestamp fields when save new object
Set current utc time to 'created_at' and 'updated_at' fields when
save this key-value pair at the first time.
"""
utcnow = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
self.created_at = utcnow
self.updated_at = utcnow
super(ModelBaseWithTimeStamp, self).save(*args, **kwargs)
def update(self, *args, **kwargs):
"""Update 'updated_at' timestamp when udpate object
Set current utc time to 'updated_at' field when update this
key-value pair.
"""
utcnow = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
self.updated_at = utcnow
super(ModelBaseWithTimeStamp, self).update(*args, **kwargs)
class PodManager(ModelBaseWithTimeStamp):
path = "/pod_managers"
fields = {
'uuid': {
'validate': types.Text.validate
},
'name': {
'validate': types.Text.validate
},
'url': {
'validate': types.Text.validate
},
'auth': {
'validate': types.Text.validate
},
'status': {
'validate': types.Text.validate
},
'description': {
'validate': types.Text.validate
},
'location': {
'validate': types.Text.validate
},
'redfish_link': {
'validate': types.Text.validate
},
'bookmark_link': {
'validate': types.Text.validate
}
}
class Flavor(ModelBaseWithTimeStamp):
path = "/flavors"
fields = {
'uuid': {
'validate': types.Text.validate
},
'name': {
'validate': types.Text.validate
},
'properties': {
'memory': {
'capacity_mib': {
'validate': types.Text.validate
},
'type': {
'validate': types.Text.validate
},
'validate': types.Dict.validate
},
'processor': {
'total_cores': {
'validate': types.Text.validate
},
'model': {
'validate': types.Text.validate
},
'validate': types.Dict.validate
},
'validate': types.Dict.validate
}
}