def setUp(self): super(TestListOfDictOfNullableStringsField, self).setUp() self.field = fields.ListOfDictOfNullableStringsField() self.coerce_good_values = [([{ 'f': 'b', 'f1': 'b1' }, { 'f2': 'b2' }], [{ 'f': 'b', 'f1': 'b1' }, { 'f2': 'b2' }]), ([{ 'f': 1 }, { 'f1': 'b1' }], [{ 'f': '1' }, { 'f1': 'b1' }]), ([{ 'foo': None }], [{ 'foo': None }])] self.coerce_bad_values = [[{1: 'a'}], ['ham', 1], ['eggs']] self.to_primitive_values = [([{ 'f': 'b' }, { 'f1': 'b1' }, { 'f2': None }], [{ 'f': 'b' }, { 'f1': 'b1' }, { 'f2': None }])] self.from_primitive_values = [([{ 'f': 'b' }, { 'f1': 'b1' }, { 'f2': None }], [{ 'f': 'b' }, { 'f1': 'b1' }, { 'f2': None }])]
class Network(base.DrydockPersistentObject, base.DrydockObject): VERSION = '1.0' fields = { 'name': ovo_fields.StringField(), 'site': ovo_fields.StringField(), 'metalabels': ovo_fields.DictOfNullableStringsField(), 'cidr': ovo_fields.StringField(), 'vlan_id': ovo_fields.StringField(nullable=True), 'routedomain': ovo_fields.StringField(nullable=True), 'mtu': ovo_fields.IntegerField(nullable=True), 'dns_domain': ovo_fields.StringField(nullable=True), 'dns_servers': ovo_fields.StringField(nullable=True), # Keys of ranges are 'type', 'start', 'end' 'ranges': ovo_fields.ListOfDictOfNullableStringsField(), # Keys of routes are 'subnet', 'routedomain', 'gateway', 'metric' 'routes': ovo_fields.ListOfDictOfNullableStringsField(), 'dhcp_relay_self_ip': ovo_fields.StringField(nullable=True), 'dhcp_relay_upstream_target': ovo_fields.StringField(nullable=True), } def __init__(self, **kwargs): super(Network, self).__init__(**kwargs) # Network keyed on name def get_id(self): return self.get_name() def get_name(self): return self.name def get_default_gateway(self): for r in getattr(self, 'routes', []): if r.get('subnet', '') == '0.0.0.0/0': return r.get('gateway', None) return None
class ContainerPCIRequest(base.ZunPersistentObject, base.ZunObject): # Version 1.0: Add request_id VERSION = '1.0' fields = { 'count': fields.IntegerField(), 'spec': fields.ListOfDictOfNullableStringsField(), 'alias_name': fields.StringField(nullable=True), # Note(moshele): is_new is deprecated and should be removed # on major version bump 'is_new': fields.BooleanField(default=False), 'request_id': fields.UUIDField(nullable=True), } def obj_load_attr(self, attr): setattr(self, attr, None) def obj_make_compatible(self, primitive, target_version): target_version = versionutils.convert_version_to_tuple(target_version) if target_version < (1, 1) and 'request_id' in primitive: del primitive['request_id']
class Plan(base.KarborPersistentObject, base.KarborObject, base.KarborObjectDictCompat, base.KarborComparableObject): # Version 1.0: Initial version VERSION = '1.0' OPTIONAL_FIELDS = ('resources', ) DEFAULT_EXPECTED_ATTR = ('resources', ) fields = { 'id': fields.UUIDField(), 'name': fields.StringField(), 'description': fields.StringField(nullable=True), 'provider_id': fields.UUIDField(), 'project_id': fields.UUIDField(), 'status': fields.StringField(nullable=True), 'resources': fields.ListOfDictOfNullableStringsField(nullable=False), 'parameters': base.DictOfDictOfStringsField(), } # obj_extra_fields is used to hold properties that are not # usually part of the model obj_extra_fields = ['plan_resources'] def __init__(self, *args, **kwargs): super(Plan, self).__init__(*args, **kwargs) self._orig_resources = {} self._reset_resources_tracking() def obj_reset_changes(self, fields=None): super(Plan, self).obj_reset_changes(fields) self._reset_resources_tracking(fields=fields) def _reset_resources_tracking(self, fields=None): if fields is None or 'resources' in fields: self._orig_resources = (list(self.resources) if 'resources' in self else []) def obj_what_changed(self): changes = super(Plan, self).obj_what_changed() if 'resources' in self and self.resources != self._orig_resources: changes.add('resources') return changes @staticmethod def _from_db_object(context, plan, db_plan, expected_attrs=None): if expected_attrs is None: expected_attrs = [] for name, field in plan.fields.items(): if name in Plan.OPTIONAL_FIELDS: continue value = db_plan.get(name) if isinstance(field, fields.IntegerField): value = value or 0 if name == "parameters" and value is not None: value = jsonutils.loads(value) plan[name] = value # Get data from db_plan object that was queried by joined query # from DB if 'resources' in expected_attrs: resources = db_plan.get('resources', []) resources_list = [] for resource in resources: dict_temp = dict() dict_temp['id'] = resource['resource_id'] dict_temp['type'] = resource['resource_type'] dict_temp['name'] = resource['resource_name'] dict_temp['extra_info'] = (resource['resource_extra_info']) resources_list.append(dict_temp) plan.resources = resources_list plan._context = context plan.obj_reset_changes() return plan @base.remotable def create(self): if self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='create', reason=_('already created')) updates = self.karbor_obj_get_changes() parameters = updates.pop('parameters', None) if parameters is not None: updates['parameters'] = jsonutils.dumps(parameters) db_plan = db.plan_create(self._context, updates) kargs = {} if hasattr(Plan, 'DEFAULT_EXPECTED_ATTR'): kargs = {'expected_attrs': getattr(Plan, 'DEFAULT_EXPECTED_ATTR')} self._from_db_object(self._context, self, db_plan, **kargs) @base.remotable def save(self): updates = self.karbor_obj_get_changes() if updates: if 'parameters' in updates: parameters = updates.pop('parameters', None) if parameters is not None: updates['parameters'] = jsonutils.dumps(parameters) if 'resources' in updates: resources = updates.pop('resources', None) resources_objlist = db.plan_resources_update( self._context, self.id, resources) resources_dictlist = [] for resource_obj in resources_objlist: resource_dict = {} resource_dict["plan_id"] = resource_obj.get("plan_id") resource_dict["id"] = resource_obj.get("resource_id") resource_dict["type"] = resource_obj.get("resource_type") resource_dict["name"] = resource_obj.get("resource_name") resource_dict["extra_info"] = resource_obj.get( "resource_extra_info") resources_dictlist.append(resource_dict) self.resources = resources_dictlist db.plan_update(self._context, self.id, updates) self.obj_reset_changes() @base.remotable def destroy(self): with self.obj_as_admin(): db.plan_destroy(self._context, self.id)