OpenStack Identity API v3(keystone)

鉴于很多初学者苦于寻找keystone的最新V3信息,故贴出来,希望可以帮到你。

please see the update draft 2 athttps://docs.google.com/document/d/1_TkawQIa52eSBfS4pv_nx1SJeoBghIlGVZsRJJynKAM/edit


Proposed by: Joe Heck




Broad Discussion

General Theme

Themes for changes:

Querying by Name

PKI Support

Open Questions

API Resources

Users

Credentials

Tenants

Domains

Roles

Endpoint

Tokens

Policy

Actions

Rules

V3 CORE API

versions

tokens

Catalog

Identity

domains

tenants

users

credentials

roles

Policy

policies

Policy (extension? altenate?)

actions


Broad Discussion


General Theme

The general theme of this proposal is a broad CRUD based API supporting authentication and authorization needs in OpenStack. Back-end implementations of Keystone may not support all components of the API, hence an API return may be NotImplemented. This is to support Keystone as a programmatic facade to a deployment’s existing authentication and authorization system(s).

Themes for changes:

  • different style of pagination that I hope will be more effective for UI work

  • consolidate CRUD operations currently in contrib into CORE

  • adding a "url" resource attribute that's the fully qualified resource location for the keystone service

  • flatten the service catalog structure

  • added in a domains (collection of tenants)

  • restructure role API calls to be specific to user->tenant or user->domain

  • tokens are now very explicit to user+tenant combinations

  • new API mechanisms to get tenants associated with a user

  • generalized credentials associated with a user/tenant combo (ec2, pki, ssh keys, etc)

  • propose an extended policy-implementation-specific API

Querying by Name


From an interaction perspective, the REST resource should contain a canonically unique identifier; that means the id in this case. Since not all resource names are not guaranteed unique on their own this is actually a filter query, and needs to be addressed as such. Filter params definitely belong in GET request params. So something like GET /users?name=foo is the most valid. This should also be extensible to multiple params GET /users?name=foo&enabled=1.


PKI Support



After reviewing our current PKI approach, I'm pretty sure everything is backwards compatible with our existing token API, with the *potential* exception of the length of his "tokens" being too long for some tools to handle as valid URL's or header values.


A base64 encoded PKI token lands in the 1-2KB range, in his examples. This encrypted token can be handled as *unencrypted* by both clients and services that do not understand/support PKI (you can still GET /tokens/{token_id} the entire thing as an opaque string, and still pass it in an X-Auth-Token, etc).


Signed tokens can still have an ID,  so the concept of ID:value for tokens will work well. The only thing that won't work is putting the signed tokens into the URL, and the avoiding-token-in-urls scheme obviates that.


Open Questions

  • Should we enable that in the API and resources?

  • Should we include in V3 core a policy implementation specific API?

POINTS OF DISCUSSION:

  • should the query parameters for the GET resource be added to the resource directly and allowed to happen, or put into a separate URI path (such as GET /users/search?name=foo) so that the implementation can be extended and manipulated with an extension in the future?

  • The consistent use of PUT/PATCH for updating portions of a REST resource. Should we allow PUT with it’s global “update/replace” functionality? Should we only allow patch (which can change the whole thing, or just update pieces)?



API Resources

Users

  • represent individual users

  • associated with 0 or more tenants (users are not exclusive to a tenant)

    • A user associated with no tenants is useless from the perspective of OpenStack and should not ever be authenticated to any resources. It is allowed, however, to create a workflow means of acquiring or loading users from other resources and mapping them to tenants.

  • Users can associated with one or more tenants, and therefore can also be in one or more domains, the association of the domain being strictly though the tenants that user is associated with.


resource attributes:

  • id (globaly unique - PRIMARY KEY/resource ID)

  • name (globaly unique)

  • url (fully qualified resource URL)

  • enabled (optional)

  • password (optional)

  • description (optional)

  • email (optional)

  • tenant_id (optional)

  • domain_id (optional)


domain_id is implied by tenant_id, as every tenant is in a domain, but is returned here for convenience.

Credentials

  • arbitrary credentials associated with a user

  • a user may have 0 or more credentials associated

  • The type is a string, with the idea that an initially supported type will be “ec2”, but that more credentials could be supported in the future.


resource attributes:

  • id (globally unique - PRIMARY KEY/resource ID)

  • type (string) [ec2|?]

  • url (fully qualified resource URL)

  • tenant_id (optional)

  • data (blob of data)

Tenants

  • base unit of "ownership" in OpenStack

  • may have 0 or more users

  • always associated with a single domain

    • A tenant can not be in two domains at once

  • roles may be granted to a user with a specific tenant


resource attributes:

  • id (globally unique - PRIMARY KEY/resource ID)

  • name (globally unique)

  • domain_id

  • url (fully qualified resource URL)

  • enabled (boolean: True or Falseoptional)


Domains

  • a collection of tenants (no tenant may be in two domains at once)

  • roles may be granted to a user within a domain


resource attributes:

  • name (globaly unique - PRIMARY KEY/resource ID)

  • id (globally unique)

  • url (fully qualified resource URL)

  • enabled (boolean: True or False)

Roles

  • a user-facing named identifier that is used to map a collection of actions from a user to either a specific tenant or an entire domain.


resource attributes:

  • id (globally unique - PRIMARY KEY/resource ID)

  • name (globally unique)

  • url (fully qualified resource URL)

Endpoint

  • an API endpoint for an OpenStack service

  • may have 0 or more policies associated with it

  • the “extra” resource attribute is intended to allow for additional tags or attributes associated with the endpoint to allow implementations to map regionality or location if it’s appropriate for their environment.


resource attributes:

  • id (globally unique - PRIMARY KEY/resource ID)

  • service [compute|image|ec2|identity|volume|network]

  • name

  • facing [public|admin|internal]

  • extra (optional) - json blob

  • url (fully qualified resource URL)

Tokens

  • an authN/Z representation of a user/tenant pair with an expiration

  • passed between client and service APIs in HTTP request headers


resource attributes:

  • id (globally unique - PRIMARY KEY/resource ID)

  • expires

  • user_id

  • tenant_id

  • domain_id

  • url (fully qualified resource URL)


domain_id is implied by tenant_id, as every tenant is in a domain, but is returned here for convenience.

Policy

  • associated with a single endpoint


resource attributes:

  • id (globally unique - PRIMARY KEY/resource ID)

  • endpoint_id

  • policy (serialized blob)

  • url (fully qualified resource URL)


Actions and Rules are below are a potential means of extending Policy beyond what we discussed at the OpenStack Folsom design summit to provide an API that maps to the policy mechanism that is currently in use by Nova, Glance, and Keystone. An example policy file is available athttps://github.com/openstack/nova/blob/master/etc/nova/policy.json.


Actions

  • Service-facing representation of a specific action within a service

  • m2m mapping with Roles (user-facing collections of actions)


resource attributes:

  • id (globally unique - PRIMARY KEY/resource ID)

  • name (globally unique)

  • url (fully qualified resource URL)


Rules

  • Service-facing representation of a rule required to be satisfied to perform an action


Not sure this needs to be a first-class entity or just an attribute/collection of an Action; also not sure where the responsibility for parsing rules should land.


resource attributes:

  • id

  • value (non-unique, potentially string formatted)

  • url (fully qualified resource URL)

Values could be parsed by keystone and passed to the service (in which case, we need a documented list of support variable names). Alternately, it could be up to services to define their own syntax for rules, and parse them themselves.


V3 CORE API

versions

(GET) / --> get version

tokens

The key use cases we need to cover:

  • given a user name & password, get a list of tenants for the user

  • given a user name, password, and tenant - get a token

  • given *JUST* a token, validate the token and return user, tenant, roles, and potential endpoints.

  • forced expiration of a token


The "just a token" has been the starting requirement, and with PKI coming online, it provides a resource path for the tokens independent of linkages to anything else.


(POST) /tokens ==> authenticate

{

"auth": {

   "password_credentials": {

       "username": "--username-here--",

       "password": "--password-here--"

       "user_id": "--user-id-here--" <--- optional

   },

   "tenant_name": "--tenant-name-here--"

}

returns token scoped to user/tenant

(example response to be placed here)


(POST) /tokens ==> authenticate

{

"auth": {

   "password_credentials": {

       "username": "--username-here--",

       "password": "--password-here--"

       "user_id": "--user-id-here--" <--- optional

   }

}

returns list of tokens scoped to each valid tenant for the user

(example response to be placed here)


(POST) /tokens ==> authenticate

{

"auth": {

   "token": {

       "id": "--token-id-here--",

   },

   "tenant_name": "--tenant-name-here--"

}

(example response to be placed here)


(GET) /tokens ==> validate token

  • tokenID set in X-Subject-Token HTTP header

(example response to be placed here)


(HEAD) /tokens ==> validate token (head)

  • tokenID set in X-Subject-Token HTTP header

(example response to be placed here)


(DELETE) /tokens ==> remove token

  • tokenID set in X-Subject-Token HTTP header

(example response to be placed here)


(GET) /tokens/endpoints ==> endpoints_for_token

  • tokenID set in X-Subject-Token HTTP header

(example response to be placed here)


(GET) /tokens/tenants ==> get_tenants_for_token (public)

  • tokenID set in X-Subject-Token HTTP header

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

  • returns a list of tenant_id associated with the user identified by the the current token

(example response to be placed here)


Catalog

The key use cases we need to cover:

  • CRUD for services

  • retrieving the endpoints of a given service, and/or with a given facing


(GET) /endpoints ==> get_endpoints

(POST) /endpoints ==> create_endpoint

{

"name": …

"url": …

"id": ...

"service": [compute|image|ec2|identity|volume|network]

"facing": [admin|public|internal]

"extra": ... (json blob)

}

(DELETE) /endpoints/{endpoint_id} ==> delete_endpoint

Identity

The key use cases we need to cover:

  • CRUD on a user

  • associating a user with a tenant

  • CRUD on a domain

  • CRUD on a tenant

domains


(POST) /domains ==> create_domain

{

"name": …

    “enabled”: ...

"id": ...

}

(GET) /domains ==> get_all_domains

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

(GET) /domains/{domain_id} ==> get_domain

(PUT) /domains/{domain_id} ==> update_domain

(PATCH) /domains/{domain_id} ==> update_domain

(DELETE) /domains/{domain_id} ==> delete_domain

tenants


(POST) /tenants ==> create_tenant

{

"name": ...

"description": ...

"enabled": ...

"domain_id": ...

}

(GET) /tenants ==> get_all_tenants (admin)

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

(GET) /tenants/{tenant_id} ==> get_tenants

(PUT) /tenants/{tenant_id} ==> replace_tenant_info

(PATCH) /tenants/{tenant_id} ==> update_tenant

(DELETE) /tenants/{tenant_id} ==> delete_tenant

(GET) /tenants/{tenant_id}/users ==> get_users_for_tenant

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

users


(POST) /users ==> create_user

{

"tenant_id": ...

"name": ...

"password": ...

"enabled": ...

"email": ...

"description": ...

}

(GET) /users ==> get_users

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

(GET) /users/{user_id} ==> get_user

(GET) /users/{user_id}/tenants ==> get_all_user_tenants

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

(PUT) /users/{user_id} ==> update_user

(PATCH) /users/{user_id} ==> update_user

(DELETE) /users/{user_id} ==> delete_user


Note: use (PATCH) to attempt to update user password or enable/disable the user. This may return a NotImplemented if the back-end driver doesn’t allow for the functionality.

credentials

The key use cases we need to cover:

  • CRUD on a credential


(POST) /users/{user_id}/credentials/ ==> create_credential

{

"type": ... (string: "ec2")

"tenant_id": ...

"access": ...

"secret": ...

}

(GET) /users/{user_id}/credentials/ ==> get_credentials

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

(GET) /users/{user_id}/credentials/{credential_id} ==> get_credential

(DELETE) /users/{user_id}/credentials/{credential_id} ==> delete_credential

roles

The key use cases we need to cover:

  • CRUD on a role

  • Associating a role with a tenant or domain


(POST) /roles ==> create_role

{

"name": ...

}

(GET) /roles ==> get_roles

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

(GET) /roles/{role_id} ==> get_role

(DELETE) /roles/{role_id} ==> delete_role


(GET) /tenants/{tenant_id}/users/{user_id}/roles ==> get_user_roles

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

(GET) /domains/{domain_id}/users/{user_id}/roles ==> get_user_roles

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)


(PUT) /tenants/{tenant_id}/users/{user_id}/roles/{role_id} ==> add_role_to_user

(DELETE) /tenants/{tenant_id}/users/{user_id}/roles/{role_id} ==> delete_role_from_user

(PUT) /domains/{domain_id}/users/{user_id}/roles/{role_id} ==> add_role_to_user

(DELETE) /domains/{domain_id}/users/{user_id}/roles/{role_id} ==> delete_role_from_user


(GET) /domains/{domainId}/users ==> get_domain_users

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

(GET) /domains/{domainId}/tenants ==> get_domain_tenants

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)


Policy

The key use cases we need to cover:

  • CRUD on a policy

policies


(POST) /policies ==> create_policy

(GET) /policies ==> get_all_policies

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

(GET) /policies/{policy_id} ==> get_policy

(PUT) /policies/{policy_id} ==> update_policy

(DELETE) /policies/{policy_id} ==> delete_policy


Policy (extension? altenate?)


NOTE: The following sections are specific to the policy authorization mechanisms we have in place in Nova, Glance, and Keystone today. These may be more applicable to an API extension in contrib based on the implementation rather than a core API in order to keep from limiting Keystone from being an effective generic facade to an implementor’s authorization backend.


This would completely replace "policies" above, by breaking that model down into actions + m2m role/action mapping (and some sort of action/rule relationship?). policy.json currently implies a boolean-OR relationship among the set of required rules

actions


(POST) /actions ==> create_action

{

"name": ...

}

(GET) /actions ==> get_all_actions

  • query_string: page (optional)

  • query_string: per_page (optional, default 30)

  • query_string: action_name (optional) ==> get_action (example of "Querying by Name" under "Broad Discussions")

(GET) /actions/{capability_id} ==> get_action

(PUT) /actions/{capability_id} ==> update_action

(DELETE) /actions/{capability_id} ==> delete_action


For this to be useful, you need to be able to collect actions into roles...


(PUT) /roles/{role_id}/actions/{action_id} ==> add_role_action

 (empty request body)

(GET) /roles/{role_id}/actions ==> get_all_role_actions

(DELETE) /roles/{role_id}/actions/{action_id} ==> remove_role_action


And then, it's not necessarily required, but it seems useful to me that the admin API to be able to answer two questions (both requiring knowledge of a specific tenant):


  • "What actions does this token have on this tenant?"

 (GET) /tokens/{token_id}/tenants/{tenant_id}/actions ==> get_token_actions

 I imagine services could use this call, although the same information MUST be included in both the auth response and the token validation response.

  • “What actions would this user have on this tenant, if this user were to auth right now?"

 (GET) /users/{user_id}/tenants/{tenant_id}/actions ==> get_user_actions

 ^ or flip around the resource to /tenants/.../users/... -- whatever makes more sense

 I imagine the dashboard would utilize this call.


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
安装OpenStack Identity服务需要遵循以下步骤: 1. 安装依赖库: ``` sudo apt-get install python-pip python-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg-dev libyaml-dev libsqlite3-dev ``` 2. 安装Keystone: ``` sudo pip install keystone ``` 3. 配置Keystone: ``` sudo cp /etc/keystone/keystone.conf.sample /etc/keystone/keystone.conf ``` 4. 编辑Keystone配置文件: ``` sudo nano /etc/keystone/keystone.conf ``` 找到[database]部分,配置数据库连接信息: ``` [database] connection = mysql+pymysql://keystone:KEYSTONE_DBPASS@controller/keystone ``` 5. 初始化Keystone数据库: ``` sudo su -s /bin/sh -c "keystone-manage db_sync" keystone ``` 6. 生成Fernet key: ``` sudo keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone sudo keystone-manage credential_setup --keystone-user keystone --keystone-group keystone ``` 7. 启动Keystone服务: ``` sudo systemctl enable --now apache2.service sudo systemctl enable --now memcached.service ``` 8. 创建服务实体: ``` sudo keystone-manage bootstrap --bootstrap-password ADMIN_PASS \ --bootstrap-admin-url http://controller:35357/v3/ \ --bootstrap-internal-url http://controller:35357/v3/ \ --bootstrap-public-url http://controller:5000/v3/ \ --bootstrap-region-id RegionOne ``` 其中,ADMIN_PASS为管理员密码。 9. 验证Keystone服务: ``` sudo openstack --os-auth-url http://controller:35357/v3 \ --os-project-domain-name Default --os-user-domain-name Default \ --os-project-name admin --os-username admin token issue ``` 如果返回一个有效的令牌,则说明Keystone服务已经成功安装并运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值