-
-
Save nikosmeds/3738f24853c85d27548645a75807b973 to your computer and use it in GitHub Desktop.
## Applying the following Keystone policy overrides with openstack-ansible. | |
keystone_policy_overrides: | |
cloud_admin: "role:admin and (is_admin_project:True or domain_id:238eb8a7ec424998b439d716c423dbde)" | |
admin_required: "role:admin" | |
admin_and_matching_user_domain_id: "rule:admin_required and domain_id:%(user.domain_id)s" | |
identity:create_user: "rule:cloud_admin or rule:admin_and_matching_user_domain_id" | |
## Confirm the cloud_admin alias' domain_id matches the `cloud_admin` domain. | |
$ openstack domain show cloud_admin | |
+-------------+----------------------------------+ | |
| Field | Value | | |
+-------------+----------------------------------+ | |
| description | Cloud admin domain | | |
| enabled | True | | |
| id | 238eb8a7ec424998b439d716c423dbde | | |
| name | cloud_admin | | |
| tags | [] | | |
+-------------+----------------------------------+ | |
$ openstack domain show product_test | |
+-------------+----------------------------------+ | |
| Field | Value | | |
+-------------+----------------------------------+ | |
| description | Niko product test domain | | |
| enabled | True | | |
| id | 5abad140eb3349c2b55ba9cf419f493c | | |
| name | product_test | | |
| tags | [] | | |
+-------------+----------------------------------+ | |
## Create project and user within the product_test domain. | |
$ openstack project create --domain product_test product_test2 | |
+-------------+----------------------------------+ | |
| Field | Value | | |
+-------------+----------------------------------+ | |
| description | | | |
| domain_id | 5abad140eb3349c2b55ba9cf419f493c | | |
| enabled | True | | |
| id | 2b3dda2239374ba98240dfd476af487d | | |
| is_domain | False | | |
| name | product_test2 | | |
| parent_id | 5abad140eb3349c2b55ba9cf419f493c | | |
| tags | [] | | |
+-------------+----------------------------------+ | |
$ openstack user create --project product_test2 --password product_test2 --domain product_test product_test2 | |
+---------------------+----------------------------------+ | |
| Field | Value | | |
+---------------------+----------------------------------+ | |
| default_project_id | 2b3dda2239374ba98240dfd476af487d | | |
| domain_id | 5abad140eb3349c2b55ba9cf419f493c | | |
| enabled | True | | |
| id | d6f0bc2a452c4775be2e22d61fd10993 | | |
| name | product_test2 | | |
| options | {} | | |
| password_expires_at | None | | |
+---------------------+----------------------------------+ | |
$ openstack role add admin --user product_test2 --user-domain product_test --project product_test2 | |
## Load the environment variable configuration file. | |
$ cat openrc-product-test2 | |
export LC_ALL=C | |
# COMMON CINDER ENVS | |
export CINDER_ENDPOINT_TYPE=internalURL | |
# COMMON NOVA ENVS | |
export NOVA_ENDPOINT_TYPE=internalURL | |
# COMMON OPENSTACK ENVS | |
export OS_ENDPOINT_TYPE=internalURL | |
export OS_INTERFACE=internalURL | |
export OS_USERNAME=product_test2 | |
export OS_PASSWORD=product_test2 | |
export OS_PROJECT_NAME=product_test2 | |
export OS_TENANT_NAME=product_test2 | |
export OS_AUTH_TYPE=password | |
export OS_AUTH_URL=http://10.103.0.8:5000/v3 | |
export OS_NO_CACHE=1 | |
export OS_USER_DOMAIN_NAME=product_test | |
export OS_PROJECT_DOMAIN_NAME=product_test | |
export OS_REGION_NAME=RegionOne | |
# For openstackclient | |
export OS_IDENTITY_API_VERSION=3 | |
export OS_AUTH_VERSION=3 | |
$ source openrc-product-test2 | |
$ openstack user create product_test3 --password product_test3 | |
+---------------------+----------------------------------+ | |
| Field | Value | | |
+---------------------+----------------------------------+ | |
| domain_id | default | | |
| enabled | True | | |
| id | d7eaab191f8544c1b86cf01520d3b065 | | |
| name | product_test3 | | |
| options | {} | | |
| password_expires_at | None | | |
+---------------------+----------------------------------+ |
Reminder to self: add --debug
to any CLI command.
It isn't helping with my above problem, but hey - it's good to remember.
Alright... I don't want to admit to this, but I will: decided to directly test user creation with HTTP API (using curl). Was curious if issue somehow related to Python client.
- Request domain-scoped token (response not shown below, but contains token).
curl -i \
-H "Content-Type: application/json" \
-d '
{ "auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "product_test",
"domain": { "name": "product_test" },
"password": "product_test"
}
}
},
"scope": {
"domain": {
"name": "product_test"
}
}
}
}' \
"https://cloud.auto-h.net:5000/v3/auth/tokens" ; echo
- Add token as header, send user creation request.
curl -i \
-X POST \
-H "Content-Type: application/json" \
-H "X-Auth-Token: gAAAAABcBcAq72OtOU7GE5RAogLhEMvIQtbY5CdLk0Hvq4n0frBN_EPe2sWhI03PeEmYtHSylZQ6yL4hJZv1UKr9YvqVz1AvcioogUORwybiwuvJLxZbEsO5eqGe7Us2vu5WRTy8NqV5TlNkKMXkW3D4WUFOymZfi99eHxqWRwxM6jvj1mfVh0Q" \
-d '
{ "user": {
"default_project_id": "cc91843aee474f3295eb3fc46961bab3",
"domain_id": "5abad140eb3349c2b55ba9cf419f493c",
"enabled": true,
"name": "Product REST",
"password": "productrest"
}
}' \
"https://cloud.auto-h.net:5000/v3/users" ; echo
HTTP/1.1 201 Created
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 03 Dec 2018 23:49:15 GMT
Content-Type: application/json
Content-Length: 338
Vary: X-Auth-Token
x-openstack-request-id: req-cd8ab7e9-37fa-4bb0-815b-ed09b653c9f8
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'self' https: wss:;
X-Frame-Options: DENY
{"user": {"name": "Product REST", "links": {"self": "https://cloud.auto-h.net:5000/v3/users/940f01d8819f4700a9fd017fea474e37"}, "domain_id": "5abad140eb3349c2b55ba9cf419f493c", "enabled": true, "options": {}, "default_project_id": "cc91843aee474f3295eb3fc46961bab3", "id": "940f01d8819f4700a9fd017fea474e37", "password_expires_at": null}}
Yeah I've left passwords in this and previous comments - will destroy these users once testing complete.
... but more importantly - it worked.
$ openstack user list --domain product_test
+----------------------------------+---------------+
| ID | Name |
+----------------------------------+---------------+
| 1bbd32cd2371468fab764ea28586c235 | product_test |
| 940f01d8819f4700a9fd017fea474e37 | Product REST |
| d6f0bc2a452c4775be2e22d61fd10993 | product_test2 |
+----------------------------------+---------------+
And ensuring the product_test
token cannot create a user in cloud_admin
domain.
curl -i \
-X POST \
-H "Content-Type: application/json" \
-H "X-Auth-Token: gAAAAABcBcAq72OtOU7GE5RAogLhEMvIQtbY5CdLk0Hvq4n0frBN_EPe2sWhI03PeEmYtHSylZQ6yL4hJZv1UKr9YvqVz1AvcioogUORwybiwuvJLxZbEsO5eqGe7Us2vu5WRTy8NqV5TlNkKMXkW3D4WUFOymZfi99eHxqWRwxM6jvj1mfVh0Q" \
-d '
{ "user": {
"default_project_id": "ec1bd3dd5e4949b4907fed4cf7c95569",
"domain_id": "238eb8a7ec424998b439d716c423dbde",
"enabled": true,
"name": "Product REST",
"password": "productrest"
}
}' \
"https://cloud.auto-h.net:5000/v3/users" ; echo
HTTP/1.1 403 Forbidden
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 03 Dec 2018 23:57:10 GMT
Content-Type: application/json
Content-Length: 138
Vary: X-Auth-Token
x-openstack-request-id: req-f54c1b7e-7f27-4e1b-bd2c-25db860b9f63
{"error": {"message": "You are not authorized to perform the requested action: identity:create_user.", "code": 403, "title": "Forbidden"}}
Amazing - RBAC is working as expected. Either the Python client has an issue, or I'm configuring the environment variables wrong.
This has been rough.
It came to me, like a vision of embarrassment and shame, that most of my confusion stems from one possibility.
Ready?
$ source openrc-product-test
$ openstack token issue
+-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| domain_id | 5abad140eb3349c2b55ba9cf419f493c |
| expires | 2018-12-05T04:04:59+0000 |
| id | gAAAAABcBqWrOKQGJOoSy72gF59ieqQ_KNUGVMlzZdLNN_UAlhxZkqAZvWSI7NAxilBYm5YfCiZUNaC7_lRk7eaexP2e2gmaYJRXAy7GrCaGHgbpw4ESvDgGCWFMtP4cY5bz4AnYlEtP08cMBXRCyIjEAzQusmSh4tpueDQ38Ca6WmWvP4yzpbU |
| user_id | 1bbd32cd2371468fab764ea28586c235 |
+-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
$ openstack user list --domain product_test
You are not authorized to perform the requested action: identity:list_users. (HTTP 403) (Request-ID: req-eb49060b-7b46-4e0a-94d6-5c502f1e909c)
$ openstack user list --domain 5abad140eb3349c2b55ba9cf419f493c
+----------------------------------+---------------+
| ID | Name |
+----------------------------------+---------------+
| 1bbd32cd2371468fab764ea28586c235 | product_test |
| d2fba554a133468f9567453be72ee0b1 | product-test3 |
| d6f0bc2a452c4775be2e22d61fd10993 | product_test2 |
+----------------------------------+---------------+
The Keystone policy files compare domain ID, and therefore we must provide the API with a domain ID. Even though names and IDs have a one-to-one relationship, Keystone doesn't make that conversion and will deny actions when provided with a domain name.
This also explains why my cURL request in the previous comment was successful - I provided a domain ID.
Throwing darts in the dark here: let's allow any of the domain_id variations (shown in previous comment) just to see if ANY of them return
True
.Applied changes, and...
Ok... not good. How about we test deleting of existing users, since this applies policies to an actual target resource. Start by creating a new user (using cloud admin credentials).
Switch to
product_test
credentials, with domain-scoped token.Oh common. Okay, we're opening the
list_users
action to any admins.Applied above changes. Again, using the
product_test
user credentials with domain-scoped token.Apparently when you specify your default domain with
--domain <domain>
things break. Good times. But happy to see we can in fact delete a user created within the same domain! Let's test a bit more functionality with the same credentials.Using
cloud_admin
credentials, creating user incloud_admin
domain.Switch back to
product_test
credentials and attempt to delete the previously created user.Interesting - not permission denied, but simply states cannot find the user. Switching back to
cloud_admin
credentials to delete with same command.How about user creation? Switching to
product_test
credentials again.Yep,
create_user
suffers from same issue aslist_users
(since they target a domain and not a specific user resource). Will need to figure that out.