Enable credentials to be owned by a project

Registered by Rafael Weingartner

Problem Description
===================
When configuring/creating credentials to enable machine to machine
integrations (e.g. backup systems, auditing tools, monitoring, and others),
the used credentials belong to the project where they are being applied;
therefore, it makes sense to enable operators to assign/create
credentials that are owned by a project, and not by a combination of
project and user.

Users should still be able to create credentials for themselves, and
their projects. The goal here is to enable the creation of credentials
for projects. Therefore, the current behavior is maintained. We can then,
restrict the API to create project credentials to super admins/operators.

Proposed Change
===============
The POST "/v3/credentials" API will allow the creation of credentials
with a project ID (without user ID).

To achieve that, we need to change the API schema validation for the
POST method. Currently, it is the following.

.. code-block:: python

    credential_create = {
        'type': 'object',
        'properties': _credential_properties,
        'additionalProperties': True,
        'oneOf': [
            {
                'title': 'ec2 credential requires project_id',
                'required': ['blob', 'type', 'user_id', 'project_id'],
                'properties': {
                    'type': {
                        'enum': ['ec2']
                    }
                }
            },
            {
                'title': 'non-ec2 credential does not require project_id',
                'required': ['blob', 'type', 'user_id'],
                'properties': {
                    'type': {
                        'not': {
                            'enum': ['ec2']
                        }
                    }
                }
            }
        ]
    }

To implement the described changes, we need to change the schema to
the following.

.. code-block:: python

    credential_create = {
        'type': 'object',
        'properties': _credential_properties,
        'additionalProperties': True,
        'oneOf': [
            {
                'title': 'ec2 credential requires project_id',
                'required': ['blob', 'type', 'project_id'],
                'properties': {
                    'type': {
                        'enum': ['ec2']
                    }
                }
            },
            {
                'title': 'non-ec2 credential does not require project_id',
                'required': ['blob', 'type', 'user_id'],
                'properties': {
                    'type': {
                        'not': {
                            'enum': ['ec2']
                        }
                    }
                }
            }
        ]
    }

The above schema change will consider as mandatory either a project ID or a
user ID. This also means, we can still create credentials for a user ID and
Project ID.

Moreover, we also need to change the database schema for the `credential`
table. Currently, the field `user_id` is not nullable in the table.
Therefore, we need to convert it to a nullable column. Moreover, due to
this change, we need to enforce via Python code that the user enters at
least project ID or user ID; otherwise, it would be possible to create
credentials that do not belong to any project or user.

Assignee(s)
-----------

Primary assignees:
- Rafael <email address hidden>

Other contributors:

Work Items
----------

1) Implement proposed changes

2) Update documentation and samples

Dependencies
============

None

Blueprint information

Status:
Not started
Approver:
None
Priority:
Undefined
Drafter:
Rafael Weingartner
Direction:
Needs approval
Assignee:
Rafael Weingartner
Definition:
New
Series goal:
None
Implementation:
Unknown
Milestone target:
None

Related branches

Sprints

Whiteboard

(?)

Work Items

This blueprint contains Public information 
Everyone can see this information.

Subscribers

No subscribers.