Jump to: navigation, search

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

(Credential)
m (The trust Table)
 
(42 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
 
|+user
Line 22: 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 37: 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 47: 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
* list_users(domain_id)
+
|-
 
+
! scope="col"| domain_id
 
+
! scope="col"| name
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.
+
! scope="col"| id
 
+
|-
====group====
+
! scope="row" colspan="3"| Primary Key: (domain_id, name)
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====
+
====The ''user_group_membership'' Table====
Table in MySql
+
The user_group_membership table used in MySQL is as follows.
 
{| class="wikitable"
 
{| class="wikitable"
 
|+ user_group_membership
 
|+ user_group_membership
Line 76: 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 86: 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 94: 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 124: 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 137: 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)
 
|}
 
|}
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.
 
  
====role====
+
 
Table in MySql
+
====The ''role'' Table====
 +
The role table in MySQL is as follows.
 
{| class="wikitable"
 
{| class="wikitable"
 
|+ role
 
|+ role
Line 150: Line 167:
 
! scope="col"| extra
 
! scope="col"| extra
 
|-
 
|-
! scope="row" colspan="3"| PK->(id), UK->(name)
+
! 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.
 
The equivalent in Cassandra is two tables.
 
{| class="wikitable"
 
{| class="wikitable"
Line 161: Line 178:
 
! scope="col"| extra
 
! scope="col"| extra
 
|-
 
|-
! scope="row" colspan="3"| PK->(id)
+
! scope="row" colspan="3"| Primary Key: (id)
 
|}
 
|}
 
{| class="wikitable"
 
{| class="wikitable"
Line 169: Line 186:
 
! scope="col"| id
 
! scope="col"| id
 
|-
 
|-
! scope="row" colspan="2"| PK->(name)
+
! scope="row" colspan="2"| Primary Key: (name)
 
|}
 
|}
 
Almost all the operations here are done with role_id information. But there is an api in v2.0 which allows you to get a role by its name. So we need the name to id mapping in second table. To preserve the uniqueness of name first a row is inserted to the role_name_index table and then if succeeds then the row is inserted to the role table.
 
 
  
 
===Resource===
 
===Resource===
Line 181: Line 195:
 
* domain
 
* domain
  
====project====
+
====The ''project'' Table====
The project table in MySql
+
The project table in MySQL is as follows.
 
{| class="wikitable"
 
{| class="wikitable"
 
|+project
 
|+project
Line 194: Line 208:
 
! scope="col"| parent_id
 
! scope="col"| parent_id
 
|-
 
|-
! scope="row" colspan="7"| PK->(id), UK->(domain_id, name), K->(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)
 
|}
 
|}
This table is going under heavy changes since we started designing Cassandra backend. So we have left out HMT as of now from our design. It won't be too difficult to add it 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.
 
  
====domain====
+
{| class="wikitable"
Table in MySql
+
|+ 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"
 
{| class="wikitable"
 
|+ domain
 
|+ domain
Line 207: Line 244:
 
! scope="col"| extra
 
! scope="col"| extra
 
|-
 
|-
! scope="row" colspan="3"| PK->(id), UK->(name)
+
! scope="row" colspan="3"| Primary Key: (id), Unique Key: (name)
 
|}
 
|}
  
Again this table looks the same as role table and is modeled similarly to it.
+
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===
 
===Credential===
The credential table holds data about the user credentials, for eg. EC2 credentials.
+
The Credential backend holds data related to EC2 credentials. It has one table.  
====credential====
+
====The ''credential'' Table ====
Table in MySql
+
The credential table in MySQL is as follows.
 
{| class="wikitable"
 
{| class="wikitable"
 
|+credential
 
|+credential
Line 226: Line 280:
 
! scope="col"| extra
 
! scope="col"| extra
 
|-
 
|-
! scope="row" colspan="7"| PK->(id)
+
! scope="row" colspan="7"| Primary Key: (id)
 
|}
 
|}
  
The table has the same schema in cassandra as well.
+
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===
 
===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)
 +
|}

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)