def update(self, context, id, resource): """ Update the resource. """ try: obj = self.resource_read(id=id) except NoIdError: raise self.get_exception_notfound(id=id) id_perms = obj.get_id_perms() if not id_perms or not id_perms.enable: raise loadbalancer.StateInvalid(id=id, state=constants.PENDING_DELETE) r = resource[self.neutron_name] if r: update = False if 'description' in r and id_perms.description != r['description']: id_perms.description = r['description'] obj.set_id_perms(id_perms) update = True if 'name' in r and r['name'] != obj.get_display_name(): obj.set_display_name(r['name']) update = True if self.update_properties(obj, id, r): update = True if self.update_object(obj, id, r): update = True if update: self.resource_update(obj) return self.make_dict(obj)
def create_vip(self, context, vip): v = vip['vip'] tenant_id = self._get_tenant_id_for_create(context, v) with context.session.begin(subtransactions=True): if v['pool_id']: pool = self._get_resource(context, Pool, v['pool_id']) # validate that the pool has same tenant if pool['tenant_id'] != tenant_id: raise n_exc.NotAuthorized() # validate that the pool has same protocol if pool['protocol'] != v['protocol']: raise loadbalancer.ProtocolMismatch( vip_proto=v['protocol'], pool_proto=pool['protocol']) if pool['status'] == constants.PENDING_DELETE: raise loadbalancer.StateInvalid(state=pool['status'], id=pool['id']) else: pool = None vip_db = Vip(id=uuidutils.generate_uuid(), tenant_id=tenant_id, name=v['name'], description=v['description'], port_id=None, protocol_port=v['protocol_port'], protocol=v['protocol'], pool_id=v['pool_id'], connection_limit=v['connection_limit'], admin_state_up=v['admin_state_up'], status=constants.PENDING_CREATE) session_info = v['session_persistence'] if session_info: s_p = self._create_session_persistence_db( session_info, vip_db['id']) vip_db.session_persistence = s_p try: context.session.add(vip_db) context.session.flush() except exception.DBDuplicateEntry: raise loadbalancer.VipExists(pool_id=v['pool_id']) # create a port to reserve address for IPAM self._create_port_for_vip(context, vip_db, v['subnet_id'], v.get('address')) if pool: pool['vip_id'] = vip_db['id'] return self._make_vip_dict(vip_db)
def update_vip(self, context, id, vip): v = vip['vip'] sess_persist = v.pop('session_persistence', None) with context.session.begin(subtransactions=True): vip_db = self._get_resource(context, Vip, id) self.assert_modification_allowed(vip_db) if sess_persist: self._update_vip_session_persistence(context, id, sess_persist) else: self._delete_session_persistence(context, id) if v: try: # in case new pool already has a vip # update will raise integrity error at first query old_pool_id = vip_db['pool_id'] vip_db.update(v) # If the pool_id is changed, we need to update # the associated pools if 'pool_id' in v: new_pool = self._get_resource(context, Pool, v['pool_id']) self.assert_modification_allowed(new_pool) # check that the pool matches the tenant_id if new_pool['tenant_id'] != vip_db['tenant_id']: raise n_exc.NotAuthorized() # validate that the pool has same protocol if new_pool['protocol'] != vip_db['protocol']: raise loadbalancer.ProtocolMismatch( vip_proto=vip_db['protocol'], pool_proto=new_pool['protocol']) if new_pool['status'] == constants.PENDING_DELETE: raise loadbalancer.StateInvalid( state=new_pool['status'], id=new_pool['id']) if old_pool_id: old_pool = self._get_resource( context, Pool, old_pool_id ) old_pool['vip_id'] = None new_pool['vip_id'] = vip_db['id'] except exception.DBDuplicateEntry: raise loadbalancer.VipExists(pool_id=v['pool_id']) return self._make_vip_dict(vip_db)
def assert_modification_allowed(self, obj): status = getattr(obj, 'status', None) if status == constants.PENDING_DELETE: raise loadbalancer.StateInvalid(id=id, state=status)
def create_vip(self, context, vip): v = vip['vip'] tenant_id = self._get_tenant_id_for_create(context, v) with context.session.begin(subtransactions=True): if v['pool_id']: pool = self._get_resource(context, Pool, v['pool_id']) # validate that the pool has same tenant if pool['tenant_id'] != tenant_id: raise n_exc.NotAuthorized() # validate that the pool has same protocol if pool['protocol'] != v['protocol']: raise loadbalancer.ProtocolMismatch( vip_proto=v['protocol'], pool_proto=pool['protocol']) if pool['status'] == constants.PENDING_DELETE: raise loadbalancer.StateInvalid(state=pool['status'], id=pool['id']) vip_db = Vip(id=uuidutils.generate_uuid(), tenant_id=tenant_id, name=v['name'], description=v['description'], port_id=None, protocol_port=v['protocol_port'], protocol=v['protocol'], pool_id=v['pool_id'], connection_limit=v['connection_limit'], admin_state_up=v['admin_state_up'], status=constants.PENDING_CREATE) session_info = v['session_persistence'] if session_info: s_p = self._create_session_persistence_db( session_info, vip_db['id']) vip_db.session_persistence = s_p try: context.session.add(vip_db) context.session.flush() except exception.DBDuplicateEntry: raise loadbalancer.VipExists(pool_id=v['pool_id']) if cfg.CONF.lbaas_vip_create_port: try: # create a port to reserve address for IPAM # do it outside the transaction to avoid rpc calls self._create_port_for_vip(context, vip_db, v['subnet_id'], v.get('address')) except Exception: # catch any kind of exceptions with excutils.save_and_reraise_exception(): context.session.delete(vip_db) context.session.flush() else: try: if v.get('address') == attributes.ATTR_NOT_SPECIFIED: raise loadbalancer.VipAddressNotAssigned() filters = { 'fixed_ips': { 'subnet_id': [v['subnet_id']], 'ip_address': [v.get('address')] } } vip_ports = self._core_plugin.get_ports(context, filters=filters) if not vip_ports: raise loadbalancer.VipPortNotFound( address=v.get('address'), subnet_id=v['subnet_id']) vip_port = vip_ports[0] filters = { 'port_id': [vip_port['id']], 'protocol_port': [v['protocol_port']] } vips = self.get_vips(context, filters=filters) if vips: raise loadbalancer.VipProtocolPortInUse( address=v.get('address'), protocol_port=v['protocol_port']) vip_db.port_id = vip_port['id'] # explicitly sync session with db context.session.flush() except Exception: # catch any kind of exceptions with excutils.save_and_reraise_exception(): context.session.delete(vip_db) context.session.flush() if v['pool_id']: # fetching pool again pool = self._get_resource(context, Pool, v['pool_id']) # (NOTE): we rely on the fact that pool didn't change between # above block and here vip_db['pool_id'] = v['pool_id'] pool['vip_id'] = vip_db['id'] # explicitly flush changes as we're outside any transaction context.session.flush() return self._make_vip_dict(vip_db)
def create_vip(self, context, vip): v = vip['vip'] tenant_id = self._get_tenant_id_for_create(context, v) with context.session.begin(subtransactions=True): if v['pool_id']: pool = self._get_resource(context, Pool, v['pool_id']) # validate that the pool has same tenant if pool['tenant_id'] != tenant_id: raise n_exc.NotAuthorized() # validate that the pool has same protocol if pool['protocol'] != v['protocol']: raise loadbalancer.ProtocolMismatch( vip_proto=v['protocol'], pool_proto=pool['protocol']) if pool['status'] == constants.PENDING_DELETE: raise loadbalancer.StateInvalid(state=pool['status'], id=pool['id']) vip_db = Vip(id=uuidutils.generate_uuid(), tenant_id=tenant_id, name=v['name'], description=v['description'], port_id=None, protocol_port=v['protocol_port'], protocol=v['protocol'], pool_id=v['pool_id'], connection_limit=v['connection_limit'], admin_state_up=v['admin_state_up'], status=constants.PENDING_CREATE) session_info = v['session_persistence'] if session_info: s_p = self._create_session_persistence_db( session_info, vip_db['id']) vip_db.session_persistence = s_p try: context.session.add(vip_db) context.session.flush() except exception.DBDuplicateEntry: raise loadbalancer.VipExists(pool_id=v['pool_id']) try: # create a port to reserve address for IPAM # do it outside the transaction to avoid rpc calls self._create_port_for_vip(context, vip_db, v['subnet_id'], v.get('address')) except Exception: # catch any kind of exceptions with excutils.save_and_reraise_exception(): context.session.delete(vip_db) context.session.flush() if v['pool_id']: # fetching pool again pool = self._get_resource(context, Pool, v['pool_id']) # (NOTE): we rely on the fact that pool didn't change between # above block and here vip_db['pool_id'] = v['pool_id'] pool['vip_id'] = vip_db['id'] # explicitly flush changes as we're outside any transaction context.session.flush() return self._make_vip_dict(vip_db)