class DeploymentReportSerializer(NotEmptySerializer): """Serializer for the Fingerprint model.""" # Scan information report_type = CharField(read_only=True) report_version = CharField(max_length=64, read_only=True) report_platform_id = UUIDField(format='hex_verbose', read_only=True) details_report = PrimaryKeyRelatedField( queryset=DetailsReport.objects.all()) report_id = IntegerField(read_only=True) cached_fingerprints = CustomJSONField(read_only=True) cached_masked_fingerprints = CustomJSONField(read_only=True) cached_csv = CharField(read_only=True) cached_masked_csv = CharField(read_only=True) cached_insights = CharField(read_only=True) status = ChoiceField(read_only=True, choices=DeploymentsReport.STATUS_CHOICES) system_fingerprints = FingerprintField(many=True, read_only=True) class Meta: """Meta class for DeploymentReportSerializer.""" model = DeploymentsReport fields = '__all__'
class ProductSerializer(NotEmptySerializer): """Serializer for the Product model.""" version = CustomJSONField(required=False) metadata = CustomJSONField(required=True) class Meta: """Meta class for ProductSerializer.""" model = Product fields = ('name', 'version', 'presence', 'metadata')
class ScanOptionsSerializer(NotEmptySerializer): """Serializer for the ScanOptions model.""" max_concurrency = IntegerField(required=False, min_value=1, default=50) disable_optional_products = CustomJSONField(required=False) class Meta: """Metadata for serializer.""" model = ScanOptions fields = ['max_concurrency', 'disable_optional_products'] # pylint: disable=invalid-name @staticmethod def validate_disable_optional_products(disable_optional_products): """Make sure that extra vars are a dictionary with boolean values.""" disable_optional_products = ScanJob.get_optional_products( disable_optional_products) if not isinstance(disable_optional_products, dict): raise ValidationError(_(messages.SJ_EXTRA_VARS_DICT)) for key in disable_optional_products: if not isinstance(disable_optional_products[key], bool): raise ValidationError(_(messages.SJ_EXTRA_VARS_BOOL)) elif key not in [ScanJob.JBOSS_EAP, ScanJob.JBOSS_BRMS, ScanJob.JBOSS_FUSE]: raise ValidationError(_(messages.SJ_EXTRA_VARS_KEY)) return json.dumps(disable_optional_products)
class EntitlementSerializer(NotEmptySerializer): """Serializer for the Entitlement model.""" metadata = CustomJSONField(required=True) class Meta: """Meta class for EntitlementSerializer.""" model = Entitlement fields = ('name', 'entitlement_id', 'metadata')
class RawFactSerializer(NotEmptySerializer): """Serializer for the SystemInspectionResult model.""" name = CharField(required=True, max_length=1024) value = CustomJSONField(required=True) class Meta: """Metadata for serialzer.""" model = RawFact fields = ['name', 'value'] qpc_allow_empty_fields = []
class DetailsReportSerializer(NotEmptySerializer): """Serializer for the DetailsReport model.""" sources = CustomJSONField(required=True) report_id = IntegerField(read_only=True) cached_csv = CharField(required=False, read_only=True) class Meta: """Meta class for DetailsReportSerializer.""" model = DetailsReport exclude = ('id', 'deployment_report')
class FactCollectionSerializer(NotEmptySerializer): """Serializer for the FactCollection model.""" sources = CustomJSONField(required=True) csv_content = CharField(required=False, read_only=True) status = ChoiceField( read_only=True, choices=FactCollection.FC_STATUS_CHOICES) class Meta: """Meta class for FactCollectionSerializer.""" model = FactCollection fields = '__all__'
class DetailsReportSerializer(NotEmptySerializer): """Serializer for the DetailsReport model.""" report_type = CharField(read_only=True) report_version = CharField(max_length=64, read_only=True) sources = CustomJSONField(required=True) report_id = IntegerField(read_only=True) report_platform_id = UUIDField(format='hex_verbose', read_only=True) cached_csv = CharField(required=False, read_only=True) class Meta: """Meta class for DetailsReportSerializer.""" model = DetailsReport exclude = ('id', 'deployment_report')
class DeploymentReportSerializer(NotEmptySerializer): """Serializer for the Fingerprint model.""" # Scan information details_report = PrimaryKeyRelatedField( queryset=DetailsReport.objects.all()) report_id = IntegerField(read_only=True) cached_json = CustomJSONField(read_only=True) cached_csv = CharField(read_only=True) status = ChoiceField(read_only=True, choices=DeploymentsReport.STATUS_CHOICES) system_fingerprints = FingerprintField(many=True, read_only=True) class Meta: """Meta class for DeploymentReportSerializer.""" model = DeploymentsReport fields = '__all__'
class ExtendedProductSearchOptionsSerializer(NotEmptySerializer): """The extended production search options of a scan.""" jboss_eap = BooleanField(required=False) jboss_fuse = BooleanField(required=False) jboss_brms = BooleanField(required=False) jboss_ws = BooleanField(required=False) search_directories = CustomJSONField(required=False) class Meta: """Metadata for serializer.""" model = ExtendedProductSearchOptions fields = ['jboss_eap', 'jboss_fuse', 'jboss_brms', 'jboss_ws', 'search_directories'] @staticmethod def validate_search_directories(search_directories): """Validate search directories.""" try: search_directories_list = json.loads(search_directories) if not isinstance(search_directories_list, list): raise ValidationError( _(messages.SCAN_OPTIONS_EXTENDED_SEARCH_DIR_NOT_LIST)) for directory in search_directories_list: if not isinstance(directory, str): raise ValidationError( _(messages.SCAN_OPTIONS_EXTENDED_SEARCH_DIR_NOT_LIST)) invalid_paths = check_path_validity(search_directories_list) if bool(invalid_paths): raise ValidationError( _(messages.SCAN_OPTIONS_EXTENDED_SEARCH_DIR_NOT_LIST)) except json_exception_class: raise ValidationError( _(messages.SCAN_OPTIONS_EXTENDED_SEARCH_DIR_NOT_LIST)) return search_directories
class SystemFingerprintSerializer(NotEmptySerializer): """Serializer for the Fingerprint model.""" # Common facts system_platform_id = UUIDField(format='hex_verbose', read_only=True) name = CharField(required=False, max_length=256) os_name = CharField(required=False, max_length=64) os_release = CharField(required=False, max_length=128) os_version = CharField(required=False, max_length=64) infrastructure_type = ChoiceField( required=False, choices=SystemFingerprint.INFRASTRUCTURE_TYPE) mac_addresses = CustomJSONField(required=False) ip_addresses = CustomJSONField(required=False) cpu_count = IntegerField(required=False, min_value=0) architecture = CharField(required=False, max_length=64) # Network scan facts bios_uuid = CharField(required=False, max_length=36) subscription_manager_id = CharField(required=False, max_length=36) cpu_socket_count = IntegerField(required=False, min_value=0) cpu_core_count = FloatField(required=False, min_value=0) cpu_core_per_socket = IntegerField(required=False, min_value=0) system_creation_date = DateField(required=False) system_last_checkin_date = DateField(required=False) system_role = CharField(required=False, max_length=128) system_addons = JSONField(required=False) system_service_level_agreement = CharField(required=False, max_length=128) system_usage_type = CharField(required=False, max_length=128) insights_client_id = CharField(required=False, max_length=128) virtualized_type = CharField(required=False, max_length=64) # VCenter scan facts vm_state = CharField(required=False, max_length=24) vm_uuid = CharField(required=False, max_length=36) vm_dns_name = CharField(required=False, max_length=256) vm_host = CharField(required=False, max_length=128) vm_host_socket_count = IntegerField(required=False, min_value=0) vm_host_core_count = IntegerField(required=False, min_value=0) vm_cluster = CharField(required=False, max_length=128) vm_datacenter = CharField(required=False, max_length=128) products = ProductSerializer(many=True, allow_null=True, required=False) entitlements = EntitlementSerializer(many=True, allow_null=True, required=False) # Red Hat facts is_redhat = NullBooleanField(required=False) redhat_certs = CharField(required=False) # pylint: disable=invalid-name redhat_package_count = IntegerField(required=False, min_value=0) metadata = CustomJSONField(required=True) sources = CustomJSONField(required=True) etc_machine_id = CharField(required=False, max_length=48) class Meta: """Meta class for SystemFingerprintSerializer.""" model = SystemFingerprint fields = '__all__' def create(self, validated_data): """Create a system fingerprint.""" products_data = validated_data.pop('products', []) entitlements_data = validated_data.pop('entitlements', []) fingerprint = SystemFingerprint.objects.create(**validated_data) for product_data in products_data: Product.objects.create(fingerprint=fingerprint, **product_data) for entitlement_data in entitlements_data: Entitlement.objects.create(fingerprint=fingerprint, **entitlement_data) return fingerprint
class SourceSerializer(NotEmptySerializer): """Serializer for the Source model.""" name = CharField(required=True, max_length=64) source_type = ValidStringChoiceField(required=False, choices=Source.SOURCE_TYPE_CHOICES) port = IntegerField(required=False, min_value=0, allow_null=True) hosts = CustomJSONField(required=True) exclude_hosts = CustomJSONField(required=False) options = SourceOptionsSerializer(required=False, many=False) credentials = CredentialsField(many=True, queryset=Credential.objects.all()) class Meta: """Metadata for the serializer.""" model = Source fields = '__all__' @classmethod def validate_opts(cls, options, source_type): """Raise an error if options are invalid for the source type. :param options: dictionary of source options :param source_type: string denoting source type """ valid_net_options = ['use_paramiko'] valid_vc_options = ['ssl_cert_verify', 'ssl_protocol', 'disable_ssl'] valid_sat_options = ['ssl_cert_verify', 'ssl_protocol', 'disable_ssl'] if source_type == Source.SATELLITE_SOURCE_TYPE: invalid_options = [ opt for opt in options if opt not in valid_sat_options ] if invalid_options: error = { 'options': [ _(messages.SAT_INVALID_OPTIONS % ', '.join(invalid_options)) ] } raise ValidationError(error) if options.get('ssl_cert_verify') is None: options['ssl_cert_verify'] = True elif source_type == Source.VCENTER_SOURCE_TYPE: invalid_options = [ opt for opt in options if opt not in valid_vc_options ] if invalid_options: error = { 'options': [ _(messages.VC_INVALID_OPTIONS % ', '.join(invalid_options)) ] } raise ValidationError(error) if options.get('ssl_cert_verify') is None: options['ssl_cert_verify'] = True elif source_type == Source.NETWORK_SOURCE_TYPE: invalid_options = [ opt for opt in options if opt not in valid_net_options ] if invalid_options: error = { 'options': [ _(messages.NET_SSL_OPTIONS_NOT_ALLOWED % ', '.join(invalid_options)) ] } raise ValidationError(error) # pylint: disable=too-many-branches,too-many-statements @transaction.atomic def create(self, validated_data): """Create a source.""" name = validated_data.get('name') check_for_existing_name(Source.objects, name, _(messages.SOURCE_NAME_ALREADY_EXISTS % name)) if 'source_type' not in validated_data: error = {'source_type': [_(messages.SOURCE_TYPE_REQ)]} raise ValidationError(error) source_type = validated_data.get('source_type') credentials = validated_data.pop('credentials') hosts_list = validated_data.pop('hosts', None) exclude_hosts_list = validated_data.pop('exclude_hosts', None) port = None if 'port' in validated_data: port = validated_data['port'] options = validated_data.pop('options', None) if source_type == Source.NETWORK_SOURCE_TYPE: if credentials: for cred in credentials: SourceSerializer.check_credential_type(source_type, cred) if port is None: validated_data['port'] = 22 elif source_type == Source.VCENTER_SOURCE_TYPE: if port is None: validated_data['port'] = 443 if hosts_list and len(hosts_list) != 1: error = {'hosts': [_(messages.VC_ONE_HOST)]} raise ValidationError(error) if hosts_list and '[' in hosts_list[0]: error = {'hosts': [_(messages.VC_ONE_HOST)]} raise ValidationError(error) if exclude_hosts_list is not None: error = { 'exclude_hosts': [_(messages.VC_EXCLUDE_HOSTS_INCLUDED)] } raise ValidationError(error) if credentials and len(credentials) > 1: error = {'credentials': [_(messages.VC_ONE_CRED)]} raise ValidationError(error) if credentials and len(credentials) == 1: SourceSerializer.check_credential_type(source_type, credentials[0]) elif source_type == Source.SATELLITE_SOURCE_TYPE: if port is None: validated_data['port'] = 443 if hosts_list and len(hosts_list) != 1: error = {'hosts': [_(messages.SAT_ONE_HOST)]} raise ValidationError(error) if hosts_list and '[' in hosts_list[0]: error = {'hosts': [_(messages.VC_ONE_HOST)]} raise ValidationError(error) if exclude_hosts_list is not None: error = { 'exclude_hosts': [_(messages.SAT_EXCLUDE_HOSTS_INCLUDED)] } raise ValidationError(error) if credentials and len(credentials) > 1: error = {'credentials': [_(messages.SAT_ONE_CRED)]} raise ValidationError(error) if credentials and len(credentials) == 1: SourceSerializer.check_credential_type(source_type, credentials[0]) source = Source.objects.create(**validated_data) if options: SourceSerializer.validate_opts(options, source_type) options = SourceOptions.objects.create(**options) options.save() source.options = options elif not options and source_type == Source.SATELLITE_SOURCE_TYPE: options = SourceOptions() options.ssl_cert_verify = True options.save() source.options = options elif not options and source_type == Source.VCENTER_SOURCE_TYPE: options = SourceOptions() options.ssl_cert_verify = True options.save() source.options = options source.hosts = json.dumps(hosts_list) if exclude_hosts_list: source.exclude_hosts = json.dumps(exclude_hosts_list) for credential in credentials: source.credentials.add(credential) source.save() return source @transaction.atomic def update(self, instance, validated_data): """Update a source.""" # If we ever add optional fields to Source, we need to # add logic here to clear them on full update even if they are # not supplied. name = validated_data.get('name') check_for_existing_name(Source.objects, name, _(messages.SOURCE_NAME_ALREADY_EXISTS % name), search_id=instance.id) if 'source_type' in validated_data: error = {'source_type': [_(messages.SOURCE_TYPE_INV)]} raise ValidationError(error) source_type = instance.source_type credentials = validated_data.pop('credentials', None) hosts_list = validated_data.pop('hosts', None) exclude_hosts_list = validated_data.pop('exclude_hosts', None) options = validated_data.pop('options', None) if source_type == Source.NETWORK_SOURCE_TYPE: if credentials: for cred in credentials: SourceSerializer.check_credential_type(source_type, cred) elif source_type == Source.VCENTER_SOURCE_TYPE: if hosts_list and len(hosts_list) != 1: error = {'hosts': [_(messages.VC_ONE_HOST)]} raise ValidationError(error) if hosts_list and '[' in hosts_list[0]: error = {'hosts': [_(messages.VC_ONE_HOST)]} raise ValidationError(error) if exclude_hosts_list is not None: error = { 'exclude_hosts': [_(messages.VC_EXCLUDE_HOSTS_INCLUDED)] } raise ValidationError(error) if credentials and len(credentials) > 1: error = {'credentials': [_(messages.VC_ONE_CRED)]} raise ValidationError(error) if credentials and len(credentials) == 1: SourceSerializer.check_credential_type(source_type, credentials[0]) elif source_type == Source.SATELLITE_SOURCE_TYPE: if hosts_list and len(hosts_list) != 1: error = {'hosts': [_(messages.SAT_ONE_HOST)]} raise ValidationError(error) if hosts_list and '[' in hosts_list[0]: error = {'hosts': [_(messages.VC_ONE_HOST)]} raise ValidationError(error) if exclude_hosts_list is not None: error = { 'exclude_hosts': [_(messages.SAT_EXCLUDE_HOSTS_INCLUDED)] } raise ValidationError(error) if credentials and len(credentials) > 1: error = {'credentials': [_(messages.SAT_ONE_CRED)]} raise ValidationError(error) if credentials and len(credentials) == 1: SourceSerializer.check_credential_type(source_type, credentials[0]) for name, value in validated_data.items(): setattr(instance, name, value) instance.save() # If hosts_list was not supplied and this is a full update, # then we should already have raised a ValidationError before # this point, so it's safe to use hosts_list as an indicator # of whether to replace the hosts. if hosts_list: instance.hosts = json.dumps(hosts_list) if exclude_hosts_list: instance.exclude_hosts = json.dumps(exclude_hosts_list) # credentials is safe to use as a flag for the same reason as # hosts_data above. if credentials: instance.credentials.set(credentials) if options: SourceSerializer.validate_opts(options, source_type) if instance.options is None: options = SourceOptions.objects.create(**options) options.save() instance.options = options else: self.update_options(options, instance.options) instance.save() return instance @staticmethod def update_options(options, instance_options): """Update the incoming options overlapping the existing options. :param options: the passed in options :param instance_options: the existing options """ ssl_protocol = options.pop('ssl_protocol', None) ssl_cert_verify = options.pop('ssl_cert_verify', None) disable_ssl = options.pop('disable_ssl', None) use_paramiko = options.pop('use_paramiko', None) if ssl_protocol is not None: instance_options.ssl_protocol = ssl_protocol if ssl_cert_verify is not None: instance_options.ssl_cert_verify = ssl_cert_verify if disable_ssl is not None: instance_options.disable_ssl = disable_ssl if use_paramiko is not None: instance_options.use_paramiko = use_paramiko instance_options.save() @staticmethod def check_credential_type(source_type, credential): """Look for existing credential with same type as the source. :param source_type: The source type :param credential: The credential to obtain """ if credential.cred_type != source_type: error = {'source_type': [_(messages.SOURCE_CRED_WRONG_TYPE)]} raise ValidationError(error) @staticmethod def validate_name(name): """Validate the name of the Source.""" if not isinstance(name, str) or not name.isprintable(): raise ValidationError(_(messages.SOURCE_NAME_VALIDATION)) return name # pylint: disable=too-many-locals, too-many-branches, too-many-statements @staticmethod def validate_ipaddr_list(hosts): """Make sure the hosts list is present and has valid IP addresses.""" ipaddr_list = json.loads(hosts) if isinstance(ipaddr_list, list): ipaddr_list = [item for item in ipaddr_list if item] if not isinstance(ipaddr_list, list): raise ValidationError(_(messages.SOURCE_HOST_MUST_BE_JSON_ARRAY)) if not ipaddr_list: raise ValidationError(_(messages.SOURCE_HOSTS_CANNOT_BE_EMPTY)) for host_value in ipaddr_list: if not isinstance(host_value, str): raise ValidationError( _(messages.SOURCE_HOST_MUST_BE_JSON_ARRAY)) # Regex for octet, CIDR bit range, and check # to see if it is like an IP/CIDR octet_regex = r'(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])' bit_range = r'(3[0-2]|[1-2][0-9]|[0-9])' relaxed_ip_pattern = r'[0-9]*\.[0-9]*\.[0-9\[\]:]*\.[0-9\[\]:]*' relaxed_cidr_pattern = r'[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\/[0-9]*' greedy_subset = r'[0-9]*' range_subset = r'[0-9]*-[0-9]*' relaxed_invalid_ip_range = [ r'{0}\.{0}\.{0}\.{0}-{0}\.{0}\.{0}\.{0}'.format(greedy_subset), r'{0}\.{0}\.{0}\.{1}'.format(greedy_subset, range_subset), r'{0}\.{0}\.{1}\.{0}'.format(greedy_subset, range_subset), r'{0}\.{1}\.{0}\.{0}'.format(greedy_subset, range_subset), r'{1}\.{0}\.{0}\.{0}'.format(greedy_subset, range_subset), r'{1}\.{1}\.{0}\.{0}'.format(greedy_subset, range_subset), r'{1}\.{0}\.{1}\.{0}'.format(greedy_subset, range_subset), r'{1}\.{0}\.{0}\.{1}'.format(greedy_subset, range_subset), r'{1}\.{1}\.{0}\.{1}'.format( greedy_subset, range_subset), r'{1}\.{0}\.{1}\.{1}'.format( greedy_subset, range_subset), r'{0}\.{0}\.{0}\.{0}'.format(range_subset), r'{0}\.{1}\.{0}\.{1}'.format(greedy_subset, range_subset), r'{0}\.{1}\.{1}\.{0}'.format(greedy_subset, range_subset) ] # type IP: 192.168.0.1 # type CIDR: 192.168.0.0/16 # type RANGE 1: 192.168.0.[1:15] # type RANGE 2: 192.168.[2:18].1 # type RANGE 3: 192.168.[2:18].[4:46] ip_regex_list = [ r'^{0}\.{0}\.{0}\.{0}$'.format(octet_regex), r'^{0}\.{0}\.{0}\.{0}\/{1}$'.format(octet_regex, bit_range), r'^{0}\.{0}\.{0}\.\[{0}:{0}\]$'.format(octet_regex), r'^{0}\.{0}\.\[{0}:{0}\]\.{0}$'.format(octet_regex), r'^{0}\.{0}\.\[{0}:{0}\]\.\[{0}:{0}\]$'.format(octet_regex) ] # type HOST: abcd # type HOST NUMERIC RANGE: abcd[2:4].foo.com # type HOST ALPHA RANGE: abcd[a:f].foo.com host_regex_list = [ r'[a-zA-Z0-9-_\.]+', r'[a-zA-Z0-9-_\.]*\[[0-9]+:[0-9]+\]*[a-zA-Z0-9-_\.]*', r'[a-zA-Z0-9-_\.]*\[[a-zA-Z]{1}:[a-zA-Z]{1}\][a-zA-Z0-9-_\.]*' ] normalized_hosts = [] host_errors = [] for host_range in ipaddr_list: result = None ip_match = re.match(relaxed_ip_pattern, host_range) cidr_match = re.match(relaxed_cidr_pattern, host_range) invalid_ip_range_match = [ re.match(invalid_ip_range, host_range) for invalid_ip_range in relaxed_invalid_ip_range ] is_likely_ip = ip_match and ip_match.end() == len(host_range) is_likely_cidr = cidr_match and cidr_match.end() == len(host_range) is_likely_invalid_ip_range = any(invalid_ip_range_match) if is_likely_invalid_ip_range: err_message = _(messages.NET_INVALID_RANGE_FORMAT % (host_range, )) result = ValidationError(err_message) elif is_likely_ip or is_likely_cidr: # This is formatted like an IP or CIDR # (e.g. #.#.#.# or #.#.#.#/#) for reg in ip_regex_list: match = re.match(reg, host_range) if match and match.end() == len(host_range): result = host_range break if result is None or is_likely_cidr: # Attempt to convert CIDR to ansible range if is_likely_cidr: try: normalized_cidr = SourceSerializer \ .cidr_to_ansible(host_range) result = normalized_cidr except ValidationError as validate_error: result = validate_error else: err_message = _(messages.NET_INVALID_RANGE_CIDR % (host_range, )) result = ValidationError(err_message) else: # Possibly a host_range addr for reg in host_regex_list: match = re.match(reg, host_range) if match and match.end() == len(host_range): result = host_range break if result is None: err_message = _(messages.NET_INVALID_HOST % (host_range, )) result = ValidationError(err_message) if isinstance(result, ValidationError): host_errors.append(result) elif result is not None: normalized_hosts.append(result) else: # This is an unexpected case. Allow/log for analysis normalized_hosts.append(host_range) logging.warning('%s did not match a pattern or produce error', host_range) if not host_errors: return normalized_hosts error_message = [error.detail.pop() for error in host_errors] raise ValidationError(error_message) @staticmethod def validate_hosts(hosts): """Validate hosts list.""" return SourceSerializer.validate_ipaddr_list(hosts) @staticmethod def validate_exclude_hosts(exclude_hosts): """Validate exclude_hosts list.""" return SourceSerializer.validate_ipaddr_list(exclude_hosts) # pylint: disable=too-many-locals @staticmethod def cidr_to_ansible(ip_range): """Convert an IP address range from CIDR to Ansible notation. :param ip_range: the IP range, as a string :returns: the IP range, as an Ansible-formatted string :raises NotCIDRException: if ip_range doesn't look similar to CIDR notation. If it does look like CIDR but isn't quite right, print out error messages and exit. """ # In the case of an input error, we want to distinguish between # strings that are "CIDR-like", so the user probably intended to # use CIDR and we should give them a CIDR error message, and not # at all CIDR-like, in which case we tell the caller to parse it a # different way. cidr_like = r'[0-9\.]*/[0-9]+' if not re.match(cidr_like, ip_range): err_msg = _(messages.NET_NO_CIDR_MATCH % (ip_range, str(cidr_like))) raise ValidationError(err_msg) try: base_address, prefix_bits = ip_range.split('/') except ValueError: err_msg = _(messages.NET_CIDR_INVALID % (ip_range, )) raise ValidationError(err_msg) prefix_bits = int(prefix_bits) if prefix_bits < 0 or prefix_bits > 32: err_msg = _(messages.NET_CIDR_BIT_MASK % { 'ip_range': ip_range, 'prefix_bits': prefix_bits }) raise ValidationError(err_msg) octet_strings = base_address.split('.') if len(octet_strings) != 4: err_msg = _(messages.NET_FOUR_OCTETS % (ip_range, )) raise ValidationError(err_msg) octets = [None] * 4 for i in range(4): if not octet_strings[i]: err_msg = _(messages.NET_EMPTY_OCTET % (ip_range, )) raise ValidationError(err_msg) val = int(octet_strings[i]) if val < 0 or val > 255: # pylint: disable=too-many-locals err_msg = _(messages.NET_CIDR_RANGE % { 'ip_range': ip_range, 'octet': val }) raise ValidationError(err_msg) octets[i] = val ansible_out = [None] * 4 for i in range(4): # "prefix_bits" is the number of high-order bits we want to # keep for the whole CIDR range. "mask" is the number of # low-order bits we want to mask off. Here prefix_bits is for # the whole IP address, but mask_bits is just for this octet. if prefix_bits <= i * 8: ansible_out[i] = '[0:255]' elif prefix_bits >= (i + 1) * 8: ansible_out[i] = str(octets[i]) else: # The number of bits of this octet that we want to # preserve this_octet_bits = prefix_bits - 8 * i assert 0 < this_octet_bits < 8 # mask is this_octet_bits 1's followed by (8 - # this_octet_bits) 0's. mask = -1 << (8 - this_octet_bits) lower_bound = octets[i] & mask upper_bound = lower_bound + ~mask ansible_out[i] = '[{0}:{1}]'.format(lower_bound, upper_bound) return '.'.join(ansible_out) @staticmethod def validate_port(port): """Validate the port.""" if not port: pass elif port < 0 or port > 65536: raise ValidationError(_(messages.NET_INVALID_PORT)) return port @staticmethod def validate_credentials(credentials): """Make sure the credentials list is present.""" if not credentials: raise ValidationError(_(messages.SOURCE_MIN_CREDS)) return credentials
class FingerprintSerializer(ModelSerializer): """Serializer for the Fingerprint model.""" # Scan information fact_collection_id = PrimaryKeyRelatedField( queryset=FactCollection.objects.all()) # Common facts name = CharField(required=False, max_length=256) os_name = CharField(required=False, max_length=64) os_release = CharField(required=False, max_length=128) os_version = CharField(required=False, max_length=64) infrastructure_type = ChoiceField( required=False, choices=SystemFingerprint.INFRASTRUCTURE_TYPE) virtualized_is_guest = NullBooleanField(default=None) mac_addresses = CustomJSONField(required=False) ip_addresses = CustomJSONField(required=False) cpu_count = IntegerField(required=False, min_value=0) # Network scan facts bios_uuid = CharField(required=False, max_length=36) subscription_manager_id = CharField(required=False, max_length=36) cpu_core_per_socket = IntegerField(required=False, min_value=0) cpu_siblings = IntegerField(required=False, min_value=0) cpu_hyperthreading = NullBooleanField(required=False) cpu_socket_count = IntegerField(required=False, min_value=0) cpu_core_count = IntegerField(required=False, min_value=0) system_creation_date = DateField(required=False) virtualized_type = CharField(required=False, max_length=64) virtualized_num_guests = IntegerField(required=False, min_value=0) virtualized_num_running_guests = IntegerField(required=False, min_value=0) # VCenter scan facts vm_state = CharField(required=False, max_length=24) vm_uuid = CharField(required=False, max_length=36) vm_memory_size = IntegerField(required=False, min_value=0) vm_dns_name = CharField(required=False, max_length=128) vm_host = CharField(required=False, max_length=128) vm_host_socket_count = IntegerField(required=False, min_value=0) vm_host_cpu_cores = IntegerField(required=False, min_value=0) vm_host_cpu_threads = IntegerField(required=False, min_value=0) vm_cluster = CharField(required=False, max_length=128) vm_datacenter = CharField(required=False, max_length=128) metadata = CustomJSONField(required=True) class Meta: """Meta class for FingerprintSerializer.""" model = SystemFingerprint fields = '__all__'
class FingerprintSerializer(ModelSerializer): """Serializer for the Fingerprint model.""" # Scan information report_id = PrimaryKeyRelatedField(queryset=FactCollection.objects.all()) # Common facts name = CharField(required=False, max_length=256) os_name = CharField(required=False, max_length=64) os_release = CharField(required=False, max_length=128) os_version = CharField(required=False, max_length=64) infrastructure_type = ChoiceField( required=False, choices=SystemFingerprint.INFRASTRUCTURE_TYPE) mac_addresses = CustomJSONField(required=False) ip_addresses = CustomJSONField(required=False) cpu_count = IntegerField(required=False, min_value=0) architecture = CharField(required=False, max_length=64) # Network scan facts bios_uuid = CharField(required=False, max_length=36) subscription_manager_id = CharField(required=False, max_length=36) cpu_socket_count = IntegerField(required=False, min_value=0) cpu_core_count = IntegerField(required=False, min_value=0) system_creation_date = DateField(required=False) virtualized_type = CharField(required=False, max_length=64) # VCenter scan facts vm_state = CharField(required=False, max_length=24) vm_uuid = CharField(required=False, max_length=36) vm_dns_name = CharField(required=False, max_length=128) vm_host = CharField(required=False, max_length=128) vm_host_socket_count = IntegerField(required=False, min_value=0) vm_cluster = CharField(required=False, max_length=128) vm_datacenter = CharField(required=False, max_length=128) products = ProductSerializer(many=True, allow_null=True, required=False) entitlements = EntitlementSerializer(many=True, allow_null=True, required=False) # Red Hat facts is_redhat = NullBooleanField(required=False) redhat_certs = CharField(required=False, max_length=128) # pylint: disable=invalid-name redhat_package_count = IntegerField(required=False, min_value=0) metadata = CustomJSONField(required=True) sources = CustomJSONField(required=True) class Meta: """Meta class for FingerprintSerializer.""" model = SystemFingerprint fields = '__all__' def create(self, validated_data): """Create a system fingerprint.""" products_data = validated_data.pop('products', []) entitlements_data = validated_data.pop('entitlements', []) fingerprint = SystemFingerprint.objects.create(**validated_data) for product_data in products_data: Product.objects.create(fingerprint=fingerprint, **product_data) for entitlement_data in entitlements_data: Entitlement.objects.create(fingerprint=fingerprint, **entitlement_data) return fingerprint
class SystemFingerprintSerializer(ModelSerializer): """Serializer for the Fingerprint model.""" # Common facts name = CharField(max_length=256, **default_args) os_name = CharField(max_length=64, **default_args) os_release = CharField(max_length=128, **default_args) os_version = CharField(max_length=64, **default_args) infrastructure_type = ChoiceField( required=False, choices=SystemFingerprint.INFRASTRUCTURE_TYPE) cloud_provider = CharField(max_length=16, **default_args) mac_addresses = CustomJSONField(**default_args) ip_addresses = CustomJSONField(**default_args) cpu_count = IntegerField(min_value=0, **default_args) architecture = CharField(max_length=64, **default_args) # Network scan facts bios_uuid = CharField(max_length=36, **default_args) subscription_manager_id = CharField(max_length=36, **default_args) cpu_socket_count = IntegerField(min_value=0, **default_args) cpu_core_count = FloatField(min_value=0, **default_args) cpu_core_per_socket = IntegerField(min_value=0, **default_args) cpu_hyperthreading = BooleanField(**default_args) system_creation_date = DateField(**default_args) system_last_checkin_date = DateField(**default_args) system_purpose = JSONField(**default_args) system_role = CharField(max_length=128, **default_args) system_addons = JSONField(**default_args) system_service_level_agreement = CharField(max_length=128, **default_args) system_usage_type = CharField(max_length=128, **default_args) insights_client_id = CharField(max_length=128, **default_args) virtualized_type = CharField(max_length=64, **default_args) system_user_count = IntegerField(min_value=0, **default_args) user_login_history = CustomJSONField(**default_args) # VCenter scan facts vm_state = CharField(max_length=24, **default_args) vm_uuid = CharField(max_length=36, **default_args) vm_dns_name = CharField(max_length=256, **default_args) virtual_host_name = CharField(max_length=128, **default_args) virtual_host_uuid = CharField(max_length=36, **default_args) vm_host_socket_count = IntegerField(min_value=0, **default_args) vm_host_core_count = IntegerField(min_value=0, **default_args) vm_cluster = CharField(max_length=128, **default_args) vm_datacenter = CharField(max_length=128, **default_args) products = ProductSerializer(many=True, **default_args) entitlements = EntitlementSerializer(many=True, **default_args) # Red Hat facts is_redhat = BooleanField(**default_args) redhat_certs = CharField(**default_args) # pylint: disable=invalid-name redhat_package_count = IntegerField(min_value=0, **default_args) metadata = CustomJSONField(required=True) sources = CustomJSONField(required=True) etc_machine_id = CharField(max_length=48, **default_args) class Meta: """Meta class for SystemFingerprintSerializer.""" model = SystemFingerprint fields = '__all__' def create(self, validated_data): """Create a system fingerprint.""" products_data = validated_data.pop('products', []) entitlements_data = validated_data.pop('entitlements', []) fingerprint = SystemFingerprint.objects.create(**validated_data) for product_data in products_data: Product.objects.create(fingerprint=fingerprint, **product_data) for entitlement_data in entitlements_data: Entitlement.objects.create(fingerprint=fingerprint, **entitlement_data) return fingerprint