Ejemplo n.º 1
0
    def update_check(self, entity):
        def check_permits():
            if self.param('permits'):
                if 'login' not in self.param('permits'):
                    self.param('permits').append('login')
                permits_service = self._service.service(
                    entity.id).permits_service()
                current = [er.name for er in permits_service.list()]
                passed = self.param('permits')
                if not sorted(current) == sorted(passed):
                    if self._module.check_mode:
                        return False
                    # remove all
                    for permit in permits_service.list():
                        permits_service.permit_service(permit.id).remove()
                    # add passed permits
                    all_permits = self.get_all_permits()
                    for new_permit in passed:
                        permits_service.add(
                            otypes.Permit(id=all_permits.get(new_permit)))
                    return False
            return True

        return (check_permits()
                and equal(self.param('administrative'), entity.administrative)
                and equal(self.param('description'), entity.description))
Ejemplo n.º 2
0
    def update_address(self, attachments_service, attachment, network):
        # Check if there is any change in address assignments and
        # update it if needed:
        for ip in attachment.ip_address_assignments:
            if str(ip.ip.version) == network.get('version', 'v4'):
                changed = False
                if not equal(network.get('boot_protocol'),
                             str(ip.assignment_method)):
                    ip.assignment_method = otypes.BootProtocol(
                        network.get('boot_protocol'))
                    changed = True
                if not equal(network.get('address'), ip.ip.address):
                    ip.ip.address = network.get('address')
                    changed = True
                if not equal(network.get('gateway'), ip.ip.gateway):
                    ip.ip.gateway = network.get('gateway')
                    changed = True
                if not equal(network.get('netmask'), ip.ip.netmask):
                    ip.ip.netmask = network.get('netmask')
                    changed = True

                if changed:
                    if not self._module.check_mode:
                        attachments_service.service(
                            attachment.id).update(attachment)
                    self.changed = True
                    break
 def update_check(self, entity):
     return (
         super(DiskAttachmentsModule, self)._update_check(follow_link(self._connection, entity.disk)) and
         equal(self._module.params.get('interface'), str(entity.interface)) and
         equal(self._module.params.get('bootable'), entity.bootable) and
         equal(self.param('activate'), entity.active)
     )
Ejemplo n.º 4
0
    def update_check(self, entity):
        def check_custom_properties():
            if self.param('custom_properties'):
                current = []
                if entity.custom_properties:
                    current = [(cp.name, cp.regexp, str(cp.value))
                               for cp in entity.custom_properties]
                passed = [(cp.get('name'), cp.get('regexp'),
                           str(cp.get('value')))
                          for cp in self.param('custom_properties') if cp]
                return sorted(current) == sorted(passed)
            return True

        pass_through = getattr(entity.pass_through.mode, 'name', None)
        return (
            check_custom_properties() and
            # The reason why we can't use equal method, is we get None from _get_network_filter_id or _get_qos_id method, when passing empty string.
            # And when first param of equal method is None it returns true.
            self._get_network_filter_id() == getattr(entity.network_filter,
                                                     'id', None)
            and self._get_qos_id() == getattr(entity.qos, 'id', None)
            and equal(self.param('migratable'),
                      getattr(entity, 'migratable', None))
            and equal(self.param('pass_through'),
                      pass_through.lower() if pass_through else None)
            and equal(self.param('description'), entity.description)
            and equal(self.param('port_mirroring'),
                      getattr(entity, 'port_mirroring', None)))
Ejemplo n.º 5
0
 def update_check(self, entity):
     self._update_tag_assignments(entity, 'vms')
     self._update_tag_assignments(entity, 'hosts')
     return (equal(self._module.params.get('description'),
                   entity.description)
             and equal(self._module.params.get('name'), entity.name)
             and equal(self._module.params.get('parent'),
                       self._get_parent(entity)))
 def update_check(self, entity):
     return (
         equal(self._module.params.get('description'), entity.description) and
         equal(self._module.params.get('url'), entity.url) and
         equal(self._module.params.get('authentication_url'), entity.authentication_url) and
         equal(self._module.params.get('tenant_name'), getattr(entity, 'tenant_name', None)) and
         equal(self._module.params.get('username'), entity.username)
     )
Ejemplo n.º 7
0
def _permission(module, permissions_service, connection):
    for permission in permissions_service.list():
        user = follow_link(connection, permission.user)
        if (equal(module.params['user_name'], user.principal if user else None)
                and equal(module.params['group_name'],
                          get_link_name(connection, permission.group))
                and equal(module.params['role'],
                          get_link_name(connection, permission.role))):
            return permission
Ejemplo n.º 8
0
 def update_check(self, entity):
     return (equal(self._cluster_network.get('required'), entity.required)
             and equal(self._cluster_network.get('display'), entity.display)
             and all(x in [
                 str(usage) for usage in getattr(entity, 'usages', [])
                 # VM + MANAGEMENT is part of root network
                 if usage != otypes.NetworkUsage.VM
                 and usage != otypes.NetworkUsage.MANAGEMENT
             ] for x in [
                 usage for usage in ['display', 'gluster', 'migration']
                 if self._cluster_network.get(usage, False)
             ]))
Ejemplo n.º 9
0
def _group(connection, module):
    groups = connection.system_service().groups_service().list(
        search="name={name}".format(
            name=module.params['name'],
        )
    )

    # If found more groups, filter them by namespace and authz name:
    # (filtering here, as oVirt/RHV backend doesn't support it)
    if len(groups) > 1:
        groups = [
            g for g in groups if (
                equal(module.params['namespace'], g.namespace) and
                equal(module.params['authz_name'], g.domain.name)
            )
        ]
    return groups[0] if groups else None
Ejemplo n.º 10
0
    def _group(self):
        groups = self._connection.system_service().groups_service().list(
            search="name={name}".format(name=self._module.params['group_name'],
                                        ))

        # If found more groups, filter them by namespace and authz name:
        # (filtering here, as oVirt/RHV backend doesn't support it)
        if len(groups) > 1:
            groups = [
                g for g in groups
                if (equal(self._module.params['namespace'], g.namespace) and
                    equal(self._module.params['authz_name'], g.domain.name))
            ]
        if not groups:
            raise Exception("Group '%s' was not found." %
                            self._module.params['group_name'])
        return groups[0]
Ejemplo n.º 11
0
    def _compare_ranges(self, entity):
        if self._module.params['ranges'] is not None:
            ranges = sorted([
                '%s,%s' % (mac_range.from_, mac_range.to)
                for mac_range in entity.ranges
            ])
            return equal(sorted(self._module.params['ranges']), ranges)

        return True
Ejemplo n.º 12
0
 def _update_check(self, entity):
     return (
         equal(self._module.params.get('name'), entity.name) and
         equal(self._module.params.get('description'), entity.description) and
         equal(self.param('quota_id'), getattr(entity.quota, 'id', None)) and
         equal(convert_to_bytes(self._module.params.get('size')), entity.provisioned_size) and
         equal(self._module.params.get('shareable'), entity.shareable) and
         equal(self.param('propagate_errors'), entity.propagate_errors) and
         equal(otypes.ScsiGenericIO(self.param('scsi_passthrough')) if self.param('scsi_passthrough') else None, entity.sgio) and
         equal(self.param('wipe_after_delete'), entity.wipe_after_delete)
     )
Ejemplo n.º 13
0
 def update_check(self, entity):
     return (
         equal(self.param('comment'), entity.comment) and
         equal(self.param('description'), entity.description) and
         equal(self.param('backup'), entity.backup) and
         equal(self.param('critical_space_action_blocker'), entity.critical_space_action_blocker) and
         equal(self.param('discard_after_delete'), entity.discard_after_delete) and
         equal(self.param('wipe_after_delete'), entity.wipe_after_delete) and
         equal(self.param('warning_low_space_indicator'), entity.warning_low_space_indicator)
     )
Ejemplo n.º 14
0
 def update_check(self, entity):
     return (
         equal(self._module.params.get('name'), entity.name) and
         equal(self._module.params.get('cluster'), get_link_name(self._connection, entity.cluster)) and
         equal(self._module.params.get('description'), entity.description) and
         equal(self._module.params.get('comment'), entity.comment) and
         equal(self._module.params.get('vm_per_user'), entity.max_user_vms) and
         equal(self._module.params.get('prestarted'), entity.prestarted_vms) and
         equal(self._module.params.get('vm_count'), entity.size)
     )
Ejemplo n.º 15
0
    def has_update(self, nic_service):
        update = False
        bond = self._module.params['bond']
        networks = self._module.params['networks']
        labels = self._module.params['labels']
        nic = get_entity(nic_service)

        if nic is None:
            return update

        # Check if bond configuration should be updated:
        if bond:
            update = self.__compare_options(
                get_bond_options(bond.get('mode'), bond.get('options')),
                getattr(nic.bonding, 'options', []))
            update = update or not equal(
                sorted(bond.get('interfaces'))
                if bond.get('interfaces') else None,
                sorted(
                    get_link_name(self._connection, s)
                    for s in nic.bonding.slaves))

        # Check if labels need to be updated on interface/bond:
        if labels:
            net_labels = nic_service.network_labels_service().list()
            # If any labels which user passed aren't assigned, relabel the interface:
            if sorted(labels) != sorted([lbl.id for lbl in net_labels]):
                return True

        if not networks:
            return update

        # Check if networks attachments configuration should be updated:
        attachments_service = nic_service.network_attachments_service()
        network_names = [network.get('name') for network in networks]

        attachments = {}
        for attachment in attachments_service.list():
            name = get_link_name(self._connection, attachment.network)
            if name in network_names:
                attachments[name] = attachment

        for network in networks:
            attachment = attachments.get(network.get('name'))
            # If attachment don't exists, we need to create it:
            if attachment is None:
                return True
            self.update_custom_properties(attachments_service, attachment,
                                          network)
            self.update_address(attachments_service, attachment, network)

        return update
Ejemplo n.º 16
0
 def update_check(self, entity):
     kernel_params = self.param('kernel_params')
     return (
         equal(self.param('comment'), entity.comment) and
         equal(self.param('kdump_integration'), 'enabled' if entity.power_management.kdump_detection else 'disabled') and
         equal(self.param('spm_priority'), entity.spm.priority) and
         equal(self.param('name'), entity.name) and
         equal(self.param('power_management_enabled'), entity.power_management.enabled) and
         equal(self.param('override_display'), getattr(entity.display, 'address', None)) and
         equal(self.param('vgpu_placement'), str(entity.vgpu_placement)) and
         equal(
             sorted(kernel_params) if kernel_params else None,
             sorted(entity.os.custom_kernel_cmdline.split(' '))
         )
     )
Ejemplo n.º 17
0
 def update_check(self, entity):
     minor = self.__get_minor(
         self._module.params.get('compatibility_version'))
     major = self.__get_major(
         self._module.params.get('compatibility_version'))
     return (equal(getattr(self._get_mac_pool(), 'id', None),
                   getattr(entity.mac_pool, 'id', None))
             and equal(self._module.params.get('comment'), entity.comment)
             and equal(self._module.params.get('description'),
                       entity.description)
             and equal(self._module.params.get('name'), entity.name)
             and equal(self._module.params.get('quota_mode'),
                       str(entity.quota_mode))
             and equal(self._module.params.get('local'), entity.local)
             and equal(minor, self.__get_minor(entity.version))
             and equal(major, self.__get_major(entity.version)))
 def _update_check(self, entity):
     return (
         equal(self._module.params.get('name'), entity.name) and
         equal(self._module.params.get('description'), entity.description) and
         equal(self.param('quota_id'), getattr(entity.quota, 'id', None)) and
         equal(convert_to_bytes(self._module.params.get('size')), entity.provisioned_size) and
         equal(self._module.params.get('shareable'), entity.shareable) and
         equal(self.param('wipe_after_delete'), entity.wipe_after_delete)
     )
Ejemplo n.º 19
0
 def update_check(self, entity):
     if self._module.params.get('vm'):
         return (
             equal(self._module.params.get('interface'),
                   str(entity.interface))
             and equal(self._module.params.get('linked'), entity.linked)
             and equal(self._module.params.get('name'), str(entity.name))
             and equal(self._module.params.get('profile'),
                       get_link_name(self._connection, entity.vnic_profile))
             and equal(self._module.params.get('mac_address'),
                       entity.mac.address))
     elif self._module.params.get('template'):
         return (equal(self._module.params.get('interface'),
                       str(entity.interface))
                 and equal(self._module.params.get('linked'), entity.linked)
                 and equal(self._module.params.get('name'), str(
                     entity.name))
                 and equal(
                     self._module.params.get('profile'),
                     get_link_name(self._connection, entity.vnic_profile)))
Ejemplo n.º 20
0
 def update_check(self, entity):
     self._update_label_assignments(entity)
     return (equal(self._module.params.get('comment'), entity.comment)
             and equal(self._module.params.get('name'), entity.name)
             and equal(self._module.params.get('description'),
                       entity.description)
             and equal(self._module.params.get('vlan_tag'),
                       getattr(entity.vlan, 'id', None))
             and equal(self._module.params.get('vm_network'),
                       True if entity.usages else False)
             and equal(self._module.params.get('mtu'), entity.mtu))
Ejemplo n.º 21
0
    def update_check(self, entity):
        assigned_vms = self.assigned_vms(entity)
        do_update = (equal(self.param('description'), entity.description)
                     and equal(self.param('vm_enforcing'), entity.enforcing)
                     and equal(
                         self.param('vm_rule') == 'positive'
                         if self.param('vm_rule') else None, entity.positive)
                     and equal(self._vm_ids, assigned_vms))
        # Following attributes is supported since 4.1,
        # so return if it doesn't exist:
        if not engine_supported(self._connection, '4.1'):
            return do_update

        # Following is supported since 4.1:
        return do_update and (
            equal(
                self.param('host_rule') == 'positive' if
                self.param('host_rule') else None, entity.hosts_rule.positive)
            and equal(self.param('host_enforcing'),
                      entity.hosts_rule.enforcing)
            and equal(
                self.param('vm_rule') in ['negative', 'positive'] if
                self.param('vm_rule') else None, entity.vms_rule.enabled) and
            equal(self._host_ids, sorted([host.id for host in entity.hosts])))
Ejemplo n.º 22
0
    def update_check(self, entity):
        def check_options():
            if self.param('options'):
                current = []
                if entity.options:
                    current = [(opt.name, str(opt.value))
                               for opt in entity.options]
                passed = [(k, str(v))
                          for k, v in self.param('options').items()]
                return sorted(current) == sorted(passed)
            return True

        return (check_options()
                and equal(self._module.params.get('address'), entity.address)
                and equal(self._module.params.get('encrypt_options'),
                          entity.encrypt_options)
                and equal(self._module.params.get('username'), entity.username)
                and equal(self._module.params.get('port'), entity.port)
                and equal(self._module.params.get('type'), entity.type)
                and equal(self._module.params.get('order'), entity.order))
    def update_check(self, entity):
        # -- FIXME --
        # Note that we here always remove all cluster/storage limits, because
        # it's not currently possible to update them and then re-create the limits
        # appropriately, this shouldn't have any side-effects, but it's not considered
        # as a correct approach.
        # This feature is tracked here: https://bugzilla.redhat.com/show_bug.cgi?id=1398576
        #

        return (self.update_storage_limits(entity)
                and self.update_cluster_limits(entity)
                and equal(self._module.params.get('name'), entity.name)
                and equal(self._module.params.get('description'),
                          entity.description)
                and equal(self._module.params.get('storage_grace'),
                          entity.storage_hard_limit_pct)
                and equal(self._module.params.get('storage_threshold'),
                          entity.storage_soft_limit_pct)
                and equal(self._module.params.get('cluster_grace'),
                          entity.cluster_hard_limit_pct)
                and equal(self._module.params.get('cluster_threshold'),
                          entity.cluster_soft_limit_pct))
Ejemplo n.º 24
0
 def update_check(self, entity):
     return (self._compare_ranges(entity) and equal(
         self._module.params['allow_duplicates'], entity.allow_duplicates)
             and equal(self._module.params['description'],
                       entity.description)
             and equal(self._module.params['name'], entity.name))
Ejemplo n.º 25
0
 def update_check(self, entity):
     template_display = entity.display
     return (
         equal(self._module.params.get('cluster'), get_link_name(self._connection, entity.cluster)) and
         equal(self._module.params.get('description'), entity.description) and
         equal(self.param('operating_system'), str(entity.os.type)) and
         equal(self.param('name'), str(entity.name)) and
         equal(self.param('smartcard_enabled'), getattr(template_display, 'smartcard_enabled', False)) and
         equal(self.param('soundcard_enabled'), entity.soundcard_enabled) and
         equal(self.param('ballooning_enabled'), entity.memory_policy.ballooning) and
         equal(self.param('sso'), True if entity.sso.methods else False) and
         equal(self.param('timezone'), getattr(entity.time_zone, 'name', None)) and
         equal(self.param('usb_support'), entity.usb.enabled) and
         equal(convert_to_bytes(self.param('memory_guaranteed')), entity.memory_policy.guaranteed) and
         equal(convert_to_bytes(self.param('memory_max')), entity.memory_policy.max) and
         equal(convert_to_bytes(self.param('memory')), entity.memory) and
         equal(self._module.params.get('cpu_profile'), get_link_name(self._connection, entity.cpu_profile)) and
         equal(self.param('io_threads'), entity.io.threads)
     )
Ejemplo n.º 26
0
 def update_check(self, entity):
     return equal(True, entity.power_management.enabled)
    def update_check(self, entity):
        sched_policy = self._get_sched_policy()
        migration_policy = getattr(entity.migration, 'policy', None)
        cluster_cpu = getattr(entity, 'cpu', dict())

        def check_custom_scheduling_policy_properties():
            if self.param('scheduling_policy_properties'):
                current = []
                if entity.custom_scheduling_policy_properties:
                    current = [
                        (sp.name, str(sp.value))
                        for sp in entity.custom_scheduling_policy_properties
                    ]
                passed = [(sp.get('name'), str(sp.get('value')))
                          for sp in self.param('scheduling_policy_properties')
                          if sp]
                for p in passed:
                    if p not in current:
                        return False
            return True

        return (check_custom_scheduling_policy_properties()
                and equal(self.param('name'), entity.name)
                and equal(self.param('comment'), entity.comment)
                and equal(self.param('description'), entity.description)
                and equal(self.param('switch_type'), str(entity.switch_type))
                and equal(self.param('cpu_arch'),
                          str(getattr(cluster_cpu, 'architecture', None)))
                and equal(self.param('cpu_type'),
                          getattr(cluster_cpu, 'type', None))
                and equal(self.param('ballooning'), entity.ballooning_enabled)
                and equal(self.param('gluster'), entity.gluster_service)
                and equal(self.param('virt'), entity.virt_service) and equal(
                    self.param('threads_as_cores'), entity.threads_as_cores)
                and equal(self.param('ksm_numa'),
                          not entity.ksm.merge_across_nodes)
                and equal(self.param('ksm'), entity.ksm.enabled)
                and equal(self.param('ha_reservation'), entity.ha_reservation)
                and equal(self.param('trusted_service'),
                          entity.trusted_service)
                and equal(self.param('host_reason'),
                          entity.maintenance_reason_required)
                and equal(self.param('vm_reason'), entity.optional_reason)
                and equal(self.param('spice_proxy'),
                          getattr(entity.display, 'proxy', None))
                and equal(self.param('fence_enabled'),
                          entity.fencing_policy.enabled)
                and equal(self.param('fence_skip_if_gluster_bricks_up'),
                          entity.fencing_policy.skip_if_gluster_bricks_up)
                and equal(self.param('fence_skip_if_gluster_quorum_not_met'),
                          entity.fencing_policy.skip_if_gluster_quorum_not_met)
                and equal(self.param('fence_skip_if_sd_active'),
                          entity.fencing_policy.skip_if_sd_active.enabled)
                and equal(
                    self.param('fence_skip_if_connectivity_broken'),
                    entity.fencing_policy.skip_if_connectivity_broken.enabled)
                and equal(
                    self.param('fence_connectivity_threshold'), entity.
                    fencing_policy.skip_if_connectivity_broken.threshold)
                and equal(self.param('resilience_policy'),
                          str(entity.error_handling.on_error))
                and equal(self.param('migration_bandwidth'),
                          str(entity.migration.bandwidth.assignment_method))
                and equal(self.param('migration_auto_converge'),
                          str(entity.migration.auto_converge))
                and equal(self.param('migration_compressed'),
                          str(entity.migration.compressed))
                and equal(self.param('migration_encrypted'),
                          str(entity.migration.encrypted))
                and equal(self.param('serial_policy'),
                          str(getattr(entity.serial_number, 'policy', None)))
                and equal(self.param('serial_policy_value'),
                          getattr(entity.serial_number, 'value', None))
                and equal(
                    self.param('scheduling_policy'),
                    getattr(
                        self._connection.follow_link(entity.scheduling_policy),
                        'name', None)) and equal(self.param('firewall_type'),
                                                 str(entity.firewall_type))
                and equal(self.param('gluster_tuned_profile'),
                          getattr(entity, 'gluster_tuned_profile', None))
                and equal(self._get_policy_id(),
                          getattr(migration_policy, 'id', None))
                and equal(self._get_memory_policy(),
                          entity.memory_policy.over_commit.percent)
                and equal(
                    self.__get_minor(self.param('compatibility_version')),
                    self.__get_minor(entity.version)) and equal(
                        self.__get_major(self.param('compatibility_version')),
                        self.__get_major(entity.version))
                and equal(
                    self.param('migration_bandwidth_limit')
                    if self.param('migration_bandwidth') == 'custom' else None,
                    entity.migration.bandwidth.custom_value) and equal(
                        sorted(self.param('rng_sources'))
                        if self.param('rng_sources') else None,
                        sorted([
                            str(source)
                            for source in entity.required_rng_sources
                        ]))
                and equal(
                    get_id_by_name(
                        self._connection.system_service().mac_pools_service(),
                        self.param('mac_pool'),
                        raise_error=False), entity.mac_pool.id)
                and self._update_check_external_network_providers(entity))
 def _matches_entity(self, item, entity):
     return equal(item.get('id'), entity.id) and equal(
         item.get('name'), entity.name)
 def update_check(self, entity):
     return (
         equal(self.param('address'), entity.address) and
         equal(self.param('path'), entity.path) and
         equal(self.param('nfs_version'), str(entity.nfs_version)) and
         equal(self.param('nfs_timeout'), entity.nfs_timeo) and
         equal(self.param('nfs_retrans'), entity.nfs_retrans) and
         equal(self.param('mount_options'), entity.mount_options) and
         equal(self.param('username'), entity.username) and
         equal(self.param('port'), entity.port) and
         equal(self.param('target'), entity.target) and
         equal(self.param('type'), str(entity.type)) and
         equal(self.param('vfs_type'), entity.vfs_type)
     )
Ejemplo n.º 30
0
 def update_check(self, entity):
     cpu_mode = getattr(entity.cpu, 'mode')
     it_display = entity.display
     return (
         not self.param('kernel_params_persist')
         and equal(convert_to_bytes(self.param('memory_guaranteed')),
                   entity.memory_policy.guaranteed)
         and equal(convert_to_bytes(self.param('memory_max')),
                   entity.memory_policy.max)
         and equal(self.param('cpu_cores'), entity.cpu.topology.cores)
         and equal(self.param('cpu_sockets'), entity.cpu.topology.sockets)
         and equal(self.param('cpu_threads'), entity.cpu.topology.threads)
         and equal(self.param('cpu_mode'),
                   str(cpu_mode) if cpu_mode else None)
         and equal(self.param('type'), str(entity.type))
         and equal(self.param('name'), str(entity.name))
         and equal(self.param('operating_system'), str(entity.os.type)) and
         equal(self.param('soundcard_enabled'), entity.soundcard_enabled)
         and equal(self.param('smartcard_enabled'),
                   getattr(it_display, 'smartcard_enabled', False))
         and equal(self.param('io_threads'), entity.io.threads)
         and equal(self.param('ballooning_enabled'),
                   entity.memory_policy.ballooning)
         and equal(self.param('serial_console'),
                   getattr(entity.console, 'enabled', None))
         and equal(self.param('usb_support'), entity.usb.enabled)
         and equal(self.param('virtio_scsi'),
                   getattr(entity, 'smartcard_enabled', False))
         and equal(self.param('high_availability'),
                   entity.high_availability.enabled)
         and equal(self.param('high_availability_priority'),
                   entity.high_availability.priority) and
         equal(self.param('boot_devices'),
               [str(dev) for dev in getattr(entity.os.boot, 'devices', [])])
         and equal(self.param('description'), entity.description) and equal(
             self.param('rng_device'),
             str(entity.rng_device.source) if entity.rng_device else None)
         and equal(
             self.param('rng_bytes'),
             entity.rng_device.rate.bytes if entity.rng_device else None)
         and equal(
             self.param('rng_period'),
             entity.rng_device.rate.period if entity.rng_device else None)
         and equal(
             self.param('placement_policy'),
             str(entity.placement_policy.affinity)
             if entity.placement_policy else None))