Jump to: navigation, search

Difference between revisions of "Keystone-schema-in-cassandra"

m (The trust Table)
 
(47 intermediate revisions by 3 users not shown)
Line 1: Line 1:
The Cassandra tables for each of the backend in Keystone is described below.
+
 
 +
===Introduction===
 +
The purpose of this wiki article is to describe the Cassandra tables for each of the backends of Keystone. A discussion of the general concepts related to schema design in Cassandra has been covered [[NoSQL|separately]].
  
 
===Identity===
 
===Identity===
  
The identity backend of Keystone holds data for users, groups and user-group membership. There are three tables in relational db for holding this data.
+
The identity backend of Keystone holds data for users, groups and user-group membership. There are three tables in the MySQL DB for this purpose.
  
 
* user
 
* user
Line 9: Line 11:
 
* user_group_membership
 
* user_group_membership
  
====user====
+
====The ''user'' Table====
Table in MySql
+
The user table in MySQL is as follows.
 
{| class="wikitable"
 
{| class="wikitable"
 +
|+user
 
|-
 
|-
 
! scope="col"| id
 
! scope="col"| id
Line 21: Line 24:
 
! scope="col"| default_project_id
 
! scope="col"| default_project_id
 
|-
 
|-
! scope="row" colspan="7"| PK->(id), UK->(domain_id, name)
+
! scope="row" colspan="7"| Primary Key: (id), Unique Key: (domain_id, name)
 
|}
 
|}
  
The equivalent of this table in Cassandra is two tables.
+
The operations pertaining to this table rely on being able to access data given one of the following sets of columns: (domain_id), (domain_id, name), (id). The equivalent operations in Cassandra are supported by the following two tables.
 +
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|+ user
 
|+ user
Line 36: Line 40:
 
! scope="col"| default_project_id
 
! scope="col"| default_project_id
 
|-
 
|-
! scope="row" colspan="7"| PK->(id)
+
! scope="row" colspan="7"| Primary Key: (id)
 
|}
 
|}
  
 
{| class="wikitable"
 
{| class="wikitable"
|+ name_index
+
|+ user_name_index
 
|-
 
|-
 
! scope="col"| domain_id
 
! scope="col"| domain_id
Line 46: Line 50:
 
! scope="col"| id
 
! scope="col"| id
 
|-
 
|-
! scope="row" colspan="3"| PK->(domain_id, name)
+
! scope="row" colspan="3"| Primary Key: (domain_id, name)
 
|}
 
|}
  
* create_user(user_id, user)
+
====The ''group'' table====
 +
The group table in MySQL is similar to the user table, and is as follows.
  
* delete_user(user_id)
+
{| class="wikitable"
 +
|+group
 +
|-
 +
! scope="col"| id
 +
! scope="col"| domain_id
 +
! scope="col"| name
 +
! scope="col"| extra
 +
! scope="col"| description
 +
|-
 +
! scope="row" colspan="5"| Primary Key: (id), Unique Key: (domain_id, name)
 +
|}
  
* update_user(domain_id, user_id, user)
+
The operations pertaining to this table rely on being able to access data given one of the following sets of columns: (domain_id), (domain_id, name), (id). Keeping the equivalent data in Cassandra is done similarly to what was done with the user table, i.e., with two Cassandra tables as follows.
  
* get_user(user_id)
+
{| class="wikitable"
 +
|+group
 +
|-
 +
! scope="col"| id
 +
! scope="col"| domain_id
 +
! scope="col"| name
 +
! scope="col"| extra
 +
! scope="col"| description
 +
|-
 +
! scope="row" colspan="5"| Primary Key: (id)
 +
|}
  
* get_user_by_name(domain_id, name)
+
{| class="wikitable"
 +
|+group_name_index
 +
|-
 +
! scope="col"| domain_id
 +
! scope="col"| name
 +
! scope="col"| id
 +
|-
 +
! scope="row" colspan="3"| Primary Key: (domain_id, name)
 +
|}
  
* list_users(domain_id)
+
====The ''user_group_membership'' Table====
 
+
The user_group_membership table used in MySQL is as follows.  
 
 
From the operations it is evident that the data for user is queried on either (domain_id), or (domain_id, name) or (user_id). Based on this information, the equivalent of this table in Cassandra would consist of two tables. All the insert, update and delete for user table goes to these two table.
 
 
 
====group====
 
The group table is similar to user except few fields such as password and default_project_id. This table can be designed the same way as user.
 
 
 
====user_group_membership====
 
Table in MySql
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|+ user_group_membership
 
|+ user_group_membership
Line 75: Line 100:
 
! scope="col"| group_id
 
! scope="col"| group_id
 
|-
 
|-
! scope="row" colspan="2"| PK->(user_id, group_id), K->(group_id)
+
! scope="row" colspan="2"| Primary Key: (user_id, group_id), Key: (group_id)
 
|}
 
|}
  
The equivalent in Cassandra is
+
The operations pertaining to this table rely on accessing data given one of the following sets of columns: (user_id), (user_id, group_id), (group_id), or (group_id, user_id). There are two tables in Cassandra to store user_group_membership. All the insert, update and delete go to both the tables in Cassandra.
 +
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|+ user_group
 
|+ user_group
Line 85: Line 111:
 
! scope="col"| group_id
 
! scope="col"| group_id
 
|-
 
|-
! scope="row" colspan="2"| PK->(user_id, group_id)
+
! scope="row" colspan="2"| Primary Key: (user_id, group_id); clustering column: group_id
 
|}
 
|}
 
{| class="wikitable"
 
{| class="wikitable"
Line 93: Line 119:
 
! scope="col"| user_id
 
! scope="col"| user_id
 
|-
 
|-
! scope="row" colspan="2"| PK->(group_id, user_id)
+
! scope="row" colspan="2"| Primary Key: (group_id, user_id); clustering column: user_id
 
|}
 
|}
* add_user_to_group(user_id, group_id)
 
 
* check_user_in_group(user_id, group_id)
 
 
* remove_user_from_group(user_id, group_id)
 
 
* list_users_in_group(group_id)
 
 
* list_groups_for_user(group_id)
 
 
 
There are two types of operations here. One is based on user_id and another is based on group_id. So there are two tables in Cassandra to store user_group_membership. All the insert, update and delete go to both the tables in Cassandra.
 
  
 
===Assignment===
 
===Assignment===
  
The assignment backend holds about the role assignments. It additionally has a role_backend which stores data for all the roles. There are two tables in relational db for this backend.
+
The assignment backend holds data about the role assignments. It additionally has a "role backend" which stores data for all the roles. There are two tables in the MySQL DB.
  
 
* assignment
 
* assignment
 
* role
 
* role
  
====assignment====
+
====The ''assignment'' Table====
Table in MySql
+
The assignment table in MySQL is as follows.
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 123: Line 137:
 
! scope="col"| target_id
 
! scope="col"| target_id
 
! scope="col"| role_id
 
! scope="col"| role_id
 +
! scope="col"|inherited
 
|-
 
|-
! scope="row" colspan="4"| PK->(type, actor_id, target_id, role_id), K->(actor_id), K->(role_id)
+
! scope="row" colspan="5"| Primary Key: (type, actor_id, target_id, role_id), Key: (actor_id), Key: (role_id)
 
|}
 
|}
  
The equivalent in Cassandra is
+
The operations pertaining to this table are based on one of the following sets of columns: (type, actor_id, target_id, role_id), (type, actor_id, target_id), (actor_id), (target_id), or (role_id). This table looks the same in Cassandra. Additionally there are two secondary index on columns target_id and role_id. These are intended to be used when a role_id or target_id is deleted from Keystone.
 +
 
 +
Note: Since the Hierarchical Multi-Tenancy feature is not yet included in this schema design, the inherited column has been omitted from the Cassandra schema.
 +
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|+ assignment
 
|+ assignment
Line 136: Line 154:
 
! scope="col"| role_id
 
! scope="col"| role_id
 
|-
 
|-
! scope="row" colspan="4"| PK->(type, actor_id, target_id, role_id), SI->(target_id), SI->(role_id)
+
! scope="row" colspan="4"| Primary Key: (type, actor_id, target_id, role_id), Secondary Indices: (target_id) and (role_id)
 +
|}
 +
 
 +
 
 +
====The ''role'' Table====
 +
The role table in MySQL is as follows.
 +
{| class="wikitable"
 +
|+ role
 +
|-
 +
! scope="col"| id
 +
! scope="col"| name
 +
! scope="col"| extra
 +
|-
 +
! scope="row" colspan="3"| Primary Key: (id), Unique Key: (name)
 +
|}
 +
Most of the operations on this table are done based on role_id. There is an api in v2.0 which allows the client to get a role by its name. So we need the name to id mapping in second table. To preserve the uniqueness of the name, a row is first inserted to the role_name_index table. If that succeeds then the row is inserted to the role table.
 +
The equivalent in Cassandra is two tables.
 +
{| class="wikitable"
 +
|+ role
 +
|-
 +
! scope="col"| id
 +
! scope="col"| name
 +
! scope="col"| extra
 +
|-
 +
! scope="row" colspan="3"| Primary Key: (id)
 +
|}
 +
{| class="wikitable"
 +
|+ role_name_index
 +
|-
 +
! scope="col"| name
 +
! scope="col"| id
 +
|-
 +
! scope="row" colspan="2"| Primary Key: (name)
 +
|}
 +
 
 +
===Resource===
 +
 
 +
The resource backend holds data about projects and domains. There are two tables in this backend.
 +
* project
 +
* domain
 +
 
 +
====The ''project'' Table====
 +
The project table in MySQL is as follows.
 +
{| class="wikitable"
 +
|+project
 +
|-
 +
! scope="col"| id
 +
! scope="col"| domain_id
 +
! scope="col"| name
 +
! scope="col"| enabled
 +
! scope="col"| description
 +
! scope="col"| extra
 +
! scope="col"| parent_id
 +
|-
 +
! scope="row" colspan="7"| Primary Key:(id), Unique Key: (domain_id, name), Key: (parent_id)
 +
|}
 +
The operations pertaining to this table are based on one of the following sets of columns: (id), (domain_id), or (domain_id, name). Currently, this schema does not account for Hierarchical Multi Tenancy, which will be done later. If we leave out the parent_id part in this table, then this table looks exactly similar to user table and also is modeled exactly the same.
 +
 
 +
{| class="wikitable"
 +
|+ project
 +
|-
 +
! scope="col"| id
 +
! scope="col"| domain_id
 +
! scope="col"| name
 +
! scope="col"| enabled
 +
! scope="col"| extra
 +
! scope="col"| description
 +
|-
 +
! scope="row" colspan="6"| Primary Key: (id)
 +
|}
 +
 
 +
{| class="wikitable"
 +
|+ project_name_index
 +
|-
 +
! scope="col"| domain_id
 +
! scope="col"| name
 +
! scope="col"| id
 +
|-
 +
! scope="row" colspan="3"| Primary Key: (domain_id, name)
 +
|}
 +
 
 +
====The ''domain'' Table====
 +
The domain table in MySQL is as follows.
 +
{| class="wikitable"
 +
|+ domain
 +
|-
 +
! scope="col"| id
 +
! scope="col"| name
 +
! scope="col"| extra
 +
|-
 +
! scope="row" colspan="3"| Primary Key: (id), Unique Key: (name)
 +
|}
 +
 
 +
The operations on this table are based on the id column. These operations are supported by following tables in Cassandra.
 +
{| class="wikitable"
 +
|+ domain
 +
|-
 +
! scope="col"| id
 +
! scope="col"| name
 +
! scope="col"| extra
 +
|-
 +
! scope="row" colspan="3"| Primary Key: (id)
 +
|}
 +
{| class="wikitable"
 +
|+ domain_name_index
 +
|-
 +
! scope="col"| name
 +
! scope="col"| id
 +
|-
 +
! scope="row" colspan="2"| Primary Key: (name)
 +
|}
 +
 
 +
===Credential===
 +
The Credential backend holds data related to EC2 credentials. It has one table.
 +
====The ''credential'' Table ====
 +
The credential table in MySQL is as follows.
 +
{| class="wikitable"
 +
|+credential
 +
|-
 +
! scope="col"| id
 +
! scope="col"| user_id
 +
! scope="col"| project_id
 +
! scope="col"| blob
 +
! scope="col"| type
 +
! scope="col"| extra
 +
|-
 +
! scope="row" colspan="7"| Primary Key: (id)
 +
|}
 +
 
 +
The operations pertaining to this table are based on one of the following columns: (id), (user_id), or (project_id). These operations are supported by the following Cassandra table. Additionally as an optimization later, secondary indices can be created on columns user_id and project_id.
 +
{| class="wikitable"
 +
|+credential
 +
|-
 +
! scope="col"| id
 +
! scope="col"| user_id
 +
! scope="col"| project_id
 +
! scope="col"| blob
 +
! scope="col"| type
 +
! scope="col"| extra
 +
|-
 +
! scope="row" colspan="7"| Primary Key: (id)
 +
|}
 +
 
 +
===Trust===
 +
The Trust backend stores data related to trust delegation functionality offered to users.
 +
 
 +
====The ''trust'' and ""trust_role"" Tables====
 +
There are two tables pertaining to this backend, trust and trust_role. They are as follows.
 +
{| class="wikitable"
 +
|+trust
 +
|-
 +
! scope="col"| id
 +
! scope="col"| trustor_user_id
 +
! scope="col"| trustee_user_id
 +
! scope="col"| project_id
 +
! scope="col"| impersonation
 +
! scope="col"| deleted_at
 +
! scope="col"| expires_at
 +
! scope="col"| remaining_uses
 +
! scope="col"| extra
 +
|-
 +
! scope="row" colspan="10"| Primary Key: (id)
 +
|}
 +
 
 +
{| class="wikitable"
 +
|+trust_role
 +
|-
 +
! scope="col"| trust_id
 +
! scope="col"| role_id
 +
|-
 +
! scope="row" colspan="2"| Primary Key: (trust_id, role_id)
 +
|}
 +
 
 +
These two tables can be combined into a single table in Cassandra. The roles are stored as a set. Cassandra provides support for richer data types for its columns.
 +
 
 +
{| class="wikitable"
 +
|+trust
 +
|-
 +
! scope="col"| id
 +
! scope="col"| trustor_user_id
 +
! scope="col"| trustee_user_id
 +
! scope="col"| project_id
 +
! scope="col"| impersonation
 +
! scope="col"| deleted_at
 +
! scope="col"| expires_at
 +
! scope="col"| remaining_uses
 +
! scope="col"| extra
 +
! scope="col"| roles(set)
 +
|-
 +
! scope="row" colspan="10"| Primary Key: (id)
 
|}
 
|}
There are a lot of operations in this backend. All the operations are not written here for brevity. This table looks the same in Cassandra. There are two secondary index on columns target_id and role_id. These would come handy when a role_id or target_id is deleted from Keystone.
 

Latest revision as of 09:13, 30 April 2015

Introduction

The purpose of this wiki article is to describe the Cassandra tables for each of the backends of Keystone. A discussion of the general concepts related to schema design in Cassandra has been covered separately.

Identity

The identity backend of Keystone holds data for users, groups and user-group membership. There are three tables in the MySQL DB for this purpose.

  • user
  • group
  • user_group_membership

The user Table

The user table in MySQL is as follows.

user
id domain_id name enabled password extra default_project_id
Primary Key: (id), Unique Key: (domain_id, name)

The operations pertaining to this table rely on being able to access data given one of the following sets of columns: (domain_id), (domain_id, name), (id). The equivalent operations in Cassandra are supported by the following two tables.

user
id domain_id name enabled password extra default_project_id
Primary Key: (id)
user_name_index
domain_id name id
Primary Key: (domain_id, name)

The group table

The group table in MySQL is similar to the user table, and is as follows.

group
id domain_id name extra description
Primary Key: (id), Unique Key: (domain_id, name)

The operations pertaining to this table rely on being able to access data given one of the following sets of columns: (domain_id), (domain_id, name), (id). Keeping the equivalent data in Cassandra is done similarly to what was done with the user table, i.e., with two Cassandra tables as follows.

group
id domain_id name extra description
Primary Key: (id)
group_name_index
domain_id name id
Primary Key: (domain_id, name)

The user_group_membership Table

The user_group_membership table used in MySQL is as follows.

user_group_membership
user_id group_id
Primary Key: (user_id, group_id), Key: (group_id)

The operations pertaining to this table rely on accessing data given one of the following sets of columns: (user_id), (user_id, group_id), (group_id), or (group_id, user_id). There are two tables in Cassandra to store user_group_membership. All the insert, update and delete go to both the tables in Cassandra.

user_group
user_id group_id
Primary Key: (user_id, group_id); clustering column: group_id
group_user
group_id user_id
Primary Key: (group_id, user_id); clustering column: user_id

Assignment

The assignment backend holds data about the role assignments. It additionally has a "role backend" which stores data for all the roles. There are two tables in the MySQL DB.

  • assignment
  • role

The assignment Table

The assignment table in MySQL is as follows.

type actor_id target_id role_id inherited
Primary Key: (type, actor_id, target_id, role_id), Key: (actor_id), Key: (role_id)

The operations pertaining to this table are based on one of the following sets of columns: (type, actor_id, target_id, role_id), (type, actor_id, target_id), (actor_id), (target_id), or (role_id). This table looks the same in Cassandra. Additionally there are two secondary index on columns target_id and role_id. These are intended to be used when a role_id or target_id is deleted from Keystone.

Note: Since the Hierarchical Multi-Tenancy feature is not yet included in this schema design, the inherited column has been omitted from the Cassandra schema.

assignment
type actor_id target_id role_id
Primary Key: (type, actor_id, target_id, role_id), Secondary Indices: (target_id) and (role_id)


The role Table

The role table in MySQL is as follows.

role
id name extra
Primary Key: (id), Unique Key: (name)

Most of the operations on this table are done based on role_id. There is an api in v2.0 which allows the client to get a role by its name. So we need the name to id mapping in second table. To preserve the uniqueness of the name, a row is first inserted to the role_name_index table. If that succeeds then the row is inserted to the role table. The equivalent in Cassandra is two tables.

role
id name extra
Primary Key: (id)
role_name_index
name id
Primary Key: (name)

Resource

The resource backend holds data about projects and domains. There are two tables in this backend.

  • project
  • domain

The project Table

The project table in MySQL is as follows.

project
id domain_id name enabled description extra parent_id
Primary Key:(id), Unique Key: (domain_id, name), Key: (parent_id)

The operations pertaining to this table are based on one of the following sets of columns: (id), (domain_id), or (domain_id, name). Currently, this schema does not account for Hierarchical Multi Tenancy, which will be done later. If we leave out the parent_id part in this table, then this table looks exactly similar to user table and also is modeled exactly the same.

project
id domain_id name enabled extra description
Primary Key: (id)
project_name_index
domain_id name id
Primary Key: (domain_id, name)

The domain Table

The domain table in MySQL is as follows.

domain
id name extra
Primary Key: (id), Unique Key: (name)

The operations on this table are based on the id column. These operations are supported by following tables in Cassandra.

domain
id name extra
Primary Key: (id)
domain_name_index
name id
Primary Key: (name)

Credential

The Credential backend holds data related to EC2 credentials. It has one table.

The credential Table

The credential table in MySQL is as follows.

credential
id user_id project_id blob type extra
Primary Key: (id)

The operations pertaining to this table are based on one of the following columns: (id), (user_id), or (project_id). These operations are supported by the following Cassandra table. Additionally as an optimization later, secondary indices can be created on columns user_id and project_id.

credential
id user_id project_id blob type extra
Primary Key: (id)

Trust

The Trust backend stores data related to trust delegation functionality offered to users.

The trust and ""trust_role"" Tables

There are two tables pertaining to this backend, trust and trust_role. They are as follows.

trust
id trustor_user_id trustee_user_id project_id impersonation deleted_at expires_at remaining_uses extra
Primary Key: (id)
trust_role
trust_id role_id
Primary Key: (trust_id, role_id)

These two tables can be combined into a single table in Cassandra. The roles are stored as a set. Cassandra provides support for richer data types for its columns.

trust
id trustor_user_id trustee_user_id project_id impersonation deleted_at expires_at remaining_uses extra roles(set)
Primary Key: (id)