<s> import six <EOL> from oslo_serialization import jsonutils <EOL> from nailgun . api . v1 . validators . base import BasicValidator <EOL> from nailgun . db . sqlalchemy import models <EOL> from nailgun import errors <EOL> from nailgun . extensions . network_manager . validators . json_schema import ip_addr <EOL> from nailgun import objects <EOL> class IPAddrValidator ( BasicValidator ) : <EOL> single_schema = ip_addr . IP_ADDR_UPDATE_SCHEMA <EOL> collection_schema = ip_addr . IP_ADDRS_UPDATE_SCHEMA <EOL> updatable_fields = ( <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> ) <EOL> @ classmethod <EOL> def _check_vip_name ( cls , data , cluster ) : <EOL> network_roles = objects . Cluster . get_network_roles ( cluster ) <EOL> allowed_vip_names = set ( ) <EOL> for net_role in network_roles : <EOL> vip_info = net_role . get ( '<STR_LIT>' , { } ) . get ( '<STR_LIT>' , [ ] ) <EOL> allowed_vip_names . update ( vip [ '<STR_LIT:name>' ] for vip in vip_info ) <EOL> if data [ '<STR_LIT>' ] not in allowed_vip_names : <EOL> raise errors . InvalidData ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> . format ( data [ '<STR_LIT>' ] , cluster . id ) <EOL> ) <EOL> @ classmethod <EOL> def validate_create ( cls , data , cluster ) : <EOL> if isinstance ( data , six . string_types ) : <EOL> data = cls . validate_json ( data ) <EOL> cls . validate_schema ( data , ip_addr . VIP_CREATE_SCHEMA ) <EOL> if data . get ( '<STR_LIT>' ) is False : <EOL> raise errors . InvalidData ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> cls . _check_vip_name ( data , cluster ) <EOL> network_id = data [ "<STR_LIT>" ] <EOL> network_db = objects . NetworkGroup . get_by_uid ( network_id ) <EOL> if network_db is None : <EOL> raise errors . InvalidData ( <EOL> "<STR_LIT>" <EOL> . format ( data [ '<STR_LIT>' ] ) <EOL> ) <EOL> if network_db . nodegroup is None : <EOL> raise errors . InvalidData ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" . format ( network_db . id ) <EOL> ) <EOL> if network_db . nodegroup . cluster_id != cluster . id : <EOL> raise errors . InvalidData ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> . format ( network_id , cluster . id ) <EOL> ) <EOL> ip_db = objects . IPAddrCollection . get_all_by_addr ( data [ '<STR_LIT>' ] ) . first ( ) <EOL> if ip_db is not None : <EOL> raise errors . InvalidData ( <EOL> "<STR_LIT>" <EOL> . format ( data [ '<STR_LIT>' ] ) <EOL> ) <EOL> return data <EOL> @ classmethod <EOL> def validate_update ( cls , data , existing_obj ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( data , six . string_types ) : <EOL> data = cls . validate_json ( data ) <EOL> existing_data = dict ( existing_obj ) <EOL> bad_fields = [ ] <EOL> for field , value in six . iteritems ( data ) : <EOL> old_value = existing_data . get ( field ) <EOL> if value != old_value and field not in cls . updatable_fields : <EOL> bad_fields . append ( field ) <EOL> if bad_fields : <EOL> bad_fields_verbose = "<STR_LIT:U+002CU+0020>" . join ( repr ( bf ) for bf in bad_fields ) <EOL> raise errors . InvalidData ( <EOL> "<STR_LIT:\n>" . join ( [ <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" . format ( <EOL> bad_fields_verbose , <EOL> jsonutils . dumps ( data ) <EOL> ) <EOL> ] ) <EOL> ) <EOL> if data . get ( '<STR_LIT>' ) and data . get ( '<STR_LIT>' ) : <EOL> cls . _check_vip_addr_intersection ( existing_obj , <EOL> data [ '<STR_LIT>' ] ) <EOL> return data <EOL> @ classmethod <EOL> def _check_vip_addr_intersection ( cls , ip_instance , addr ) : <EOL> """<STR_LIT>""" <EOL> intersecting_ip = objects . IPAddrCollection . get_all_by_addr ( addr ) . first ( ) <EOL> if intersecting_ip is not None and intersecting_ip is not ip_instance : <EOL> err_msg = ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> . format ( addr , <EOL> intersecting_ip . network_data . name , <EOL> intersecting_ip . network_data . cidr ) <EOL> ) <EOL> raise errors . AlreadyExists ( err_msg ) <EOL> @ classmethod <EOL> def validate_collection_update ( cls , data , cluster_id ) : <EOL> """<STR_LIT>""" <EOL> error_messages = [ ] <EOL> data_to_update = cls . validate_json ( data ) <EOL> existing_instances = objects . IPAddrCollection . get_vips_by_cluster_id ( <EOL> cluster_id ) <EOL> for record in data_to_update : <EOL> instance = existing_instances . filter ( <EOL> models . IPAddr . id == record . get ( '<STR_LIT:id>' ) <EOL> ) . first ( ) <EOL> if instance : <EOL> try : <EOL> cls . validate_update ( record , instance ) <EOL> except errors . InvalidData as e : <EOL> error_messages . append ( e . message ) <EOL> else : <EOL> error_messages . append ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" . format ( <EOL> record . get ( '<STR_LIT:id>' ) , <EOL> cluster_id <EOL> ) <EOL> ) <EOL> if error_messages : <EOL> raise errors . InvalidData ( "<STR_LIT:\n>" . join ( error_messages ) ) <EOL> return data_to_update </s>
