Repository: ansible/awx
File: awx/main/models/inventory.py (Python)

Code before:
        are not flexible enough to allow customizing the image they use.
        """
        if self.inventory.kind == 'constructed':
            return get_control_plane_execution_environment()
        return super().resolve_execution_environment()

    @staticmethod
    def cloud_credential_validation(source, cred):
        if not source:
            return None
        if cred and source not in ('custom', 'scm', 'openshift_virtualization'):
            # If a credential was provided, it's important that it matches
            # the actual inventory source being used (Amazon requires Amazon
            # credentials; Rackspace requires Rackspace credentials; etc...)
            if source.replace('ec2', 'aws') != cred.kind:
                return _('Cloud-based inventory sources (such as %s) require credentials for the matching cloud service.') % source
        # Allow an EC2 source to omit the credential.  If Tower is running on
        # an EC2 instance with an IAM Role assigned, boto will use credentials
        # from the instance metadata instead of those explicitly provided.
        elif source in CLOUD_PROVIDERS and source not in ['ec2', 'openshift_virtualization']:
            return _('Credential is required for a cloud source.')
        elif source == 'custom' and cred and cred.credential_type.kind in ('scm', 'ssh', 'insights', 'vault'):
            return _('Credentials of type machine, source control, insights and vault are disallowed for custom inventory sources.')
        elif source == 'scm' and cred and cred.credential_type.kind in ('insights', 'vault'):
            return _('Credentials of type insights and vault are disallowed for scm inventory sources.')
        elif source == 'openshift_virtualization' and cred and cred.credential_type.kind not in ('kubernetes'):
            return _('Credentials of type kubernetes is requred for openshift_virtualization inventory sources.')
        return None

    def get_cloud_credential(self):
        """Return the credential which is directly tied to the inventory source type."""
        credential = None
        for cred in self.credentials.all():
            if self.source in CLOUD_PROVIDERS:
                if cred.kind == self.source.replace('ec2', 'aws'):
                    credential = cred
                    break
            else:
                # these need to be returned in the API credential field
                if cred.credential_type.kind != 'vault':
                    credential = cred
                    break
        return credential

    def get_extra_credentials(self):
        """Return all credentials that are not used by the inventory source injector.
        These are all credentials that should run their own inject_credential logic.
        """
        special_cred = None
        if self.source in CLOUD_PROVIDERS:
            # these have special injection logic associated with them

Review comment (security):
```suggestion
        elif source == 'openshift_virtualization' and cred and cred.credential_type.kind != 'kubernetes':
```

Code after:
        are not flexible enough to allow customizing the image they use.
        """
        if self.inventory.kind == 'constructed':
            return get_control_plane_execution_environment()
        return super().resolve_execution_environment()

    @staticmethod
    def cloud_credential_validation(source, cred):
        if not source:
            return None
        if cred and source not in ('custom', 'scm', 'openshift_virtualization'):
            # If a credential was provided, it's important that it matches
            # the actual inventory source being used (Amazon requires Amazon
            # credentials; Rackspace requires Rackspace credentials; etc...)
            if source.replace('ec2', 'aws') != cred.kind:
                return _('Cloud-based inventory sources (such as %s) require credentials for the matching cloud service.') % source
        # Allow an EC2 source to omit the credential.  If Tower is running on
        # an EC2 instance with an IAM Role assigned, boto will use credentials
        # from the instance metadata instead of those explicitly provided.
        elif source in CLOUD_PROVIDERS and source not in ['ec2', 'openshift_virtualization']:
            return _('Credential is required for a cloud source.')
        elif source == 'custom' and cred and cred.credential_type.kind in ('scm', 'ssh', 'insights', 'vault'):
            return _('Credentials of type machine, source control, insights and vault are disallowed for custom inventory sources.')
        elif source == 'scm' and cred and cred.credential_type.kind in ('insights', 'vault'):
            return _('Credentials of type insights and vault are disallowed for scm inventory sources.')
        elif source == 'openshift_virtualization' and cred and cred.credential_type.kind != 'kubernetes':
            return _('Credentials of type kubernetes is requred for openshift_virtualization inventory sources.')
        return None

    def get_cloud_credential(self):
        """Return the credential which is directly tied to the inventory source type."""
        credential = None
        for cred in self.credentials.all():
            if self.source in CLOUD_PROVIDERS:
                if cred.kind == self.source.replace('ec2', 'aws'):
                    credential = cred
                    break
            else:
                # these need to be returned in the API credential field
                if cred.credential_type.kind != 'vault':
                    credential = cred
                    break
        return credential

    def get_extra_credentials(self):
        """Return all credentials that are not used by the inventory source injector.
        These are all credentials that should run their own inject_credential logic.
        """
        special_cred = None
        if self.source in CLOUD_PROVIDERS:
            # these have special injection logic associated with them