Updating the docs to match current state
* While the incode documentation has been updated quite a bit, the readme has remained mostly untouched for too long and needed some updates. * Also added some notes about deprecation of older style taskviews that ended up never being used in production anyway. Change-Id: I7f21b68e1e37fec0bcba75eeccc35213c4e0a5c0
This commit is contained in:
parent
dba11b87d1
commit
3a35e66a66
@ -1,18 +1,18 @@
|
|||||||
# Deploying Adjutant in Devstack
|
# Deploying Adjutant in Devstack
|
||||||
|
|
||||||
This is a guide to setting up Adjutant in a running Devstack environment similar to how we have been running it for development purposes.
|
This is a guide to setting up Adjutant in a running Devstack environment close to how we have been running it for development purposes.
|
||||||
|
|
||||||
This guide assumes you are running this in a clean ubuntu 14.04 virtual machine with sudo access.
|
This guide assumes you are running this in a clean ubuntu 16.04 virtual machine with sudo access.
|
||||||
|
|
||||||
## Deploy Devstack
|
## Deploy Devstack
|
||||||
|
|
||||||
Grab the Devstack repo. For this we are going to focus on mitaka.
|
Grab the Devstack repo.
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://github.com/openstack-dev/devstack.git -b stable/mitaka
|
git clone https://github.com/openstack-dev/devstack.git
|
||||||
```
|
```
|
||||||
|
|
||||||
And then define a basic localrc file with the password set and place that in the devstack folder:
|
And then define a basic localrc file with the password set and place that in the devstack folder (adjutant's default conf assumes 'openstack' as the admin password):
|
||||||
```
|
```
|
||||||
ADMIN_PASSWORD=openstack
|
ADMIN_PASSWORD=openstack
|
||||||
MYSQL_PASSWORD=openstack
|
MYSQL_PASSWORD=openstack
|
||||||
@ -44,8 +44,9 @@ virtualenv venv
|
|||||||
source venv/bin/activate
|
source venv/bin/activate
|
||||||
```
|
```
|
||||||
|
|
||||||
Once that is done you can install Adjutant into your virtual environment, which will also install all the required python libraries:
|
Once that is done you can install Adjutant and its requirements:
|
||||||
```
|
```
|
||||||
|
pip install -r requirements.txt
|
||||||
python setup.py develop
|
python setup.py develop
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -74,8 +75,11 @@ In a new SSH termimal connected to your ubuntu VM setup your credentials as envi
|
|||||||
```
|
```
|
||||||
export OS_USERNAME=admin
|
export OS_USERNAME=admin
|
||||||
export OS_PASSWORD=openstack
|
export OS_PASSWORD=openstack
|
||||||
export OS_TENANT_NAME=demo
|
export OS_PROJECT_NAME=demo
|
||||||
export OS_AUTH_URL=http://localhost:5000/v2.0
|
export OS_USER_DOMAIN_NAME=default
|
||||||
|
export OS_PROJECT_DOMAIN_NAME=default
|
||||||
|
export OS_AUTH_URL=http://localhost:5000/
|
||||||
|
export OS_IDENTITY_API_VERSION=3
|
||||||
export OS_REGION_NAME=RegionOne
|
export OS_REGION_NAME=RegionOne
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -95,6 +99,10 @@ To allow certain actions, Adjutant requires two special roles to exist. You can
|
|||||||
openstack role create project_admin
|
openstack role create project_admin
|
||||||
openstack role create project_mod
|
openstack role create project_mod
|
||||||
```
|
```
|
||||||
|
Also because Adjutant by default also adds the role, you will want to create 'heat_stack_owner' which isn't by default present in devstack unless you install Heat:
|
||||||
|
```
|
||||||
|
openstack role create heat_stack_owner
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Testing Adjutant via the CLI
|
## Testing Adjutant via the CLI
|
||||||
@ -103,11 +111,11 @@ Now that the service is running, and the endpoint setup, you will want to instal
|
|||||||
```
|
```
|
||||||
sudo pip install python-adjutantclient
|
sudo pip install python-adjutantclient
|
||||||
```
|
```
|
||||||
In this case the client is safe to install globally as none of its requirements will conflict with OpenStack.
|
In this case the client should be safe to install globally with sudo, but you can also install it in the same virtualenv as Adjutant itself, or make a new virtualenv.
|
||||||
|
|
||||||
Now lets check the status of the service:
|
Now lets check the status of the service:
|
||||||
```
|
```
|
||||||
adjutant status
|
openstack adjutant status
|
||||||
```
|
```
|
||||||
|
|
||||||
What you should get is:
|
What you should get is:
|
||||||
@ -120,16 +128,17 @@ What you should get is:
|
|||||||
```
|
```
|
||||||
Seeing as we've done nothing to the service yet this is the expected output.
|
Seeing as we've done nothing to the service yet this is the expected output.
|
||||||
|
|
||||||
To list the users on your current project (admin users are hidden):
|
To list the users on your current project (admin users are hidden by default):
|
||||||
```
|
```
|
||||||
adjutant user-list
|
openstack project user list
|
||||||
```
|
```
|
||||||
|
The above action is only possibly for users with the following roles: 'admin', 'project_admin', 'project_mod'
|
||||||
|
|
||||||
Now lets try inviting a new user:
|
Now lets try inviting a new user:
|
||||||
```
|
```
|
||||||
adjutant user-invite --email bob@example.com --roles project_admin
|
openstack project user invite bob@example.com project_admin
|
||||||
```
|
```
|
||||||
You then then get a note saying your invitation has been sent followed by a print out of the users on your current project (same as doing 'adjutant user-list').
|
You will then get a note saying your invitation has been sent. You can list your project users again with 'openstack project user list' to see your invite.
|
||||||
|
|
||||||
|
|
||||||
Now if you look at the log in the Adjutant terminal you should still have open, you will see a print out of the email that would have been sent to bob@example.com. In the email is a line that looks like this:
|
Now if you look at the log in the Adjutant terminal you should still have open, you will see a print out of the email that would have been sent to bob@example.com. In the email is a line that looks like this:
|
||||||
@ -140,12 +149,13 @@ Normally that would direct the user to a Horizon dashboard page where they can s
|
|||||||
|
|
||||||
Since we don't have that running, your only option is to submit it via the CLI. This is cumbersome, but doable. From that url in your Adjutant output, grab the values after '.../token/'. That is bob's token. You can submit that via the CLI:
|
Since we don't have that running, your only option is to submit it via the CLI. This is cumbersome, but doable. From that url in your Adjutant output, grab the values after '.../token/'. That is bob's token. You can submit that via the CLI:
|
||||||
```
|
```
|
||||||
adjutant token-submit <bobs_token> --data '{"password": "123456"}'
|
openstack admin task token submit <token> <json_data>
|
||||||
|
openstack admin task token submit e86cbfb187d34222ace90845f900893c '{"password": "123456"}'
|
||||||
```
|
```
|
||||||
|
|
||||||
Now if you get the user list, you will see bob is now active:
|
Now if you get the user list, you will see bob is now active:
|
||||||
```
|
```
|
||||||
adjutant user-list
|
openstack project user list
|
||||||
```
|
```
|
||||||
|
|
||||||
And also shows up as a user if you do:
|
And also shows up as a user if you do:
|
||||||
@ -153,76 +163,19 @@ And also shows up as a user if you do:
|
|||||||
openstack user list
|
openstack user list
|
||||||
```
|
```
|
||||||
|
|
||||||
|
And since you are an admin, you can even take a look at the tasks themselves:
|
||||||
|
```
|
||||||
|
openstack admin task list
|
||||||
|
```
|
||||||
|
The topmost one should be your invite, and if you then do a show using that id you can see some details about it:
|
||||||
|
```
|
||||||
|
openstack admin task show <UUID>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Setting Up Adjutant on Horizon
|
## Setting Up Adjutant on Horizon
|
||||||
|
|
||||||
This is a little annoying, since we can't simple install the changes as a plugin, but for the purposes of our demo we will be using a fork of Horizon with our internal Horizon changes rebased on top.
|
Adjutant has a Horizon UI plugin, the code and setup instructions for it can be found here:
|
||||||
|
https://github.com/catalyst/adjutant-ui
|
||||||
|
|
||||||
First grab the Adjutant fork of horizon:
|
If you do set this up, you will want to edit the default Adjutant conf to so that the TOKEN_SUBMISSION_URL is correctly set to point at your Horizon.
|
||||||
```
|
|
||||||
git clone https://github.com/catalyst/horizon.git -b stable/mitaka_adjutant
|
|
||||||
```
|
|
||||||
|
|
||||||
Now we will copy the code from that repo to replace the code devstack is using:
|
|
||||||
```
|
|
||||||
cp -r horizon/* /opt/stack/horizon/
|
|
||||||
```
|
|
||||||
|
|
||||||
We will also need to add the Adjutant url to the local_settings file for the non-authed views:
|
|
||||||
```
|
|
||||||
echo 'OPENSTACK_REGISTRATION_URL="http://0.0.0.0:5050/v1"' >> /opt/stack/horizon/openstack_dashboard/local/local_settings.py
|
|
||||||
```
|
|
||||||
|
|
||||||
Now we need to restart apache:
|
|
||||||
```
|
|
||||||
sudo service apache2 restart
|
|
||||||
```
|
|
||||||
|
|
||||||
Now if you go to your devstack Horizon dashboard you will be able to access the new panel and new un-authed views.
|
|
||||||
|
|
||||||
|
|
||||||
To help testing token submission, you probably will want to update this line in the Adjutant conf from:
|
|
||||||
```
|
|
||||||
TOKEN_SUBMISSION_URL: http://192.168.122.160:8080/dashboard/token/
|
|
||||||
```
|
|
||||||
To point to the ip or url of your devstack VM:
|
|
||||||
```
|
|
||||||
TOKEN_SUBMISSION_URL: <ip_or_url_to_devstack>/dashboard/token/
|
|
||||||
```
|
|
||||||
Setting that url will mean the token links send in the emails will be usable via your Horizon.
|
|
||||||
|
|
||||||
|
|
||||||
## Sending email via a mail server
|
|
||||||
|
|
||||||
By default the conf is set to output emails to console, but if you have a mail server you can use update the conf to reflect that and the service will send emails through that.
|
|
||||||
|
|
||||||
Simply replace this part of the conf:
|
|
||||||
```yaml
|
|
||||||
EMAIL_SETTINGS:
|
|
||||||
EMAIL_BACKEND: django.core.mail.backends.console.EmailBackend
|
|
||||||
```
|
|
||||||
|
|
||||||
With this, adding in your server and port:
|
|
||||||
```yaml
|
|
||||||
EMAIL_SETTINGS:
|
|
||||||
EMAIL_BACKEND: django.core.mail.backends.smtp.EmailBackend
|
|
||||||
EMAIL_HOST: <server_url>
|
|
||||||
EMAIL_PORT: <server_port>
|
|
||||||
```
|
|
||||||
|
|
||||||
Or this if your server needs a username and password:
|
|
||||||
```yaml
|
|
||||||
EMAIL_SETTINGS:
|
|
||||||
EMAIL_BACKEND: django.core.mail.backends.smtp.EmailBackend
|
|
||||||
EMAIL_HOST: <server_url>
|
|
||||||
EMAIL_PORT: <server_port>
|
|
||||||
EMAIL_HOST_USER: <username>
|
|
||||||
EMAIL_HOST_PASSWORD: <password>
|
|
||||||
```
|
|
||||||
|
|
||||||
Once the service has reset, it should now send emails via that server rather than print them to console.
|
|
||||||
|
|
||||||
## Updating adjutant
|
|
||||||
|
|
||||||
Adjutant doesn't have a typical manage.py file, instead this functionality is installed into the virtual enviroment when adjutant is installed.
|
|
||||||
All of the expected Django functionality can be used using the 'adjutant-api' cli.
|
|
||||||
|
291
README.md
291
README.md
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
A basic workflow framework built using Django and Django-Rest-Framework to help automate basic Admin tasks within an OpenStack cluster.
|
A basic workflow framework built using Django and Django-Rest-Framework to help automate basic Admin tasks within an OpenStack cluster.
|
||||||
|
|
||||||
Primarily built as user registration service that fits into the OpenStack ecosystem alongside Keystone, its purpose to fill functionality missing from Keystone. Ultimately it is just a framework with actions that are tied to an endpoint and can require certain data fields and perform actions via the OpenStack clients.
|
Primarily built as user registration service that fits into the OpenStack ecosystem alongside Keystone, its purpose to fill functionality missing from Keystone. Ultimately it is just a framework with actions that are tied to an endpoint and can require certain data fields and perform actions via the OpenStack clients as well as talk to external systems as needed.
|
||||||
|
|
||||||
Useful for automating generic admin tasks that users might request but otherwise can't do without the admin role. Also allows automating the signup and creation of new users, but also allows such requests to require approval first if wanted. Due to issuing of uri+tokens for final steps of some actions, allows for a password submit/reset system as well.
|
Useful for automating generic admin tasks that users might request but otherwise can't do without the admin role. Also allows automating the signup and creation of new users, but also allows such requests to require approval first if wanted. Due to issuing of uri+tokens for final steps of some actions, allows for a password submit/reset system as well.
|
||||||
|
|
||||||
@ -13,65 +13,66 @@ The main workflow consists of three possible steps which can be executed at diff
|
|||||||
The base use case is three stages:
|
The base use case is three stages:
|
||||||
|
|
||||||
* Recieve Request
|
* Recieve Request
|
||||||
* Validate request data against action serializers.
|
* Validate request data against action serializers.
|
||||||
* If valid, setup Task to represent the request, and the Actions specified for that TaskView.
|
* If valid, setup Task to represent the request, and the Actions specified for that TaskView.
|
||||||
* The service runs the pre_approve function on all actions which should do any self validation to mark the actions themselves as valid or invalid, and populating the nodes in the Task based on that.
|
* The service runs the pre_approve function on all actions which should do any self validation to mark the actions themselves as valid or invalid, and populating the nodes in the Task based on that.
|
||||||
* Admin Approval
|
* Admin Approval
|
||||||
* An admin looks at the Task and its notes.
|
* An admin looks at the Task and its notes.
|
||||||
* If they decide it is safe to approve, they do so.
|
* If they decide it is safe to approve, they do so.
|
||||||
* If there are any invalid actions approval will do nothing until the action data is updated and initial validation is rerun.
|
* If there are any invalid actions approval will do nothing until the action data is updated and initial validation is rerun.
|
||||||
* The service runs the post_approve function on all actions.
|
* The service runs the post_approve function on all actions.
|
||||||
* If any of the actions require a Token to be issued and emailed for additional data such as a user password, then that will occur.
|
* If any of the actions require a Token to be issued and emailed for additional data such as a user password, then that will occur.
|
||||||
* If no Token is required, the Task will run submit actions, and be marked as complete.
|
* If no Token is required, the Task will run submit actions, and be marked as complete.
|
||||||
* Token Submit
|
* Token Submit
|
||||||
* User submits the Token data.
|
* User submits the Token data.
|
||||||
* The service runs the submit function on all actions, passing along the Token data, normally a password.
|
* The service runs the submit function on all actions, passing along the Token data, normally a password.
|
||||||
* The action will then complete with the given final data.
|
* The action will then complete with the given final data.
|
||||||
* Task is marked as complete.
|
* Task is marked as complete.
|
||||||
|
|
||||||
There are cases and TaskViews that auto-approve, and thus automatically do the middle step right after the first. There are also others which do not need a Token and thus run the submit step as part of the second, or even all three at once. The exact number of 'steps' and the time between them depends on the definition of the TaskView.
|
There are cases and TaskViews that auto-approve, and thus automatically do the middle step right after the first. There are also others which do not need a Token and thus run the submit step as part of the second, or even all three at once. The exact number of 'steps' and the time between them depends on the definition of the TaskView.
|
||||||
|
|
||||||
Actions themselves can also effectively do anything within the scope of those three stages, and there is even the ability to chain multiple actions together, and pass data along to other actions.
|
Actions themselves can also effectively do anything within the scope of those three stages, and there is even the ability to chain multiple actions together, and pass data along to other actions.
|
||||||
|
|
||||||
The points that are modular, or will be made more modular in future, are the TaskViews and the actions tied to them. Adding new actions is easy, and attaching them to existing TaskViews is as well. Adding new TaskViews is also fairly easy, but will be made more modular in future (see Future Plans).
|
The points that are modular, or will be made more modular in future, are the TaskViews and the actions tied to them. Adding new actions is easy, and attaching them to existing TaskViews is as well. Adding new TaskViews is also almost entirely modular.
|
||||||
|
|
||||||
Creation and management of Tasks, Tokens, and Notifications is not modular and is the framework around the defined Actions and TaskViews that handles how they are executed. This helps keep the way Actions are executed consistent and simpler to maintain, but does also allow Actions to run almost any logic within those consistent steps.
|
Creation and management of Tasks, Tokens, and Notifications is not modular and is the framework around the defined Actions and TaskViews that handles how they are executed. This helps keep the way Actions are executed consistent and simpler to maintain, but does also allow Actions to run almost any logic within those consistent steps.
|
||||||
|
|
||||||
#### Admin Endpoints:
|
#### Admin Endpoints:
|
||||||
|
|
||||||
Endpoints for the management of tasks, tokens, and notifications. Most of these are limited by roles, and are for admin use only.
|
Endpoints for the management of tasks, tokens, and notifications. Most of these are limited by roles, or are for admin use only.
|
||||||
|
|
||||||
* ../v1/tasks - GET
|
* ../v1/tasks - GET
|
||||||
* A json containing all tasks.
|
* A json containing all tasks.
|
||||||
* Possible parameters are:
|
* Possible parameters are:
|
||||||
* filters (specified below)
|
* filters (specified below)
|
||||||
* tasks_per_page, defaults to 25
|
* tasks_per_page, defaults to 25
|
||||||
* page, page number to access (starts at 1)
|
* page, page number to access (starts at 1)
|
||||||
* ../v1/tasks/<uuid> - GET
|
* ../v1/tasks/<uuid> - GET
|
||||||
* Get details for a specific task.
|
* Get details for a specific task.
|
||||||
* ../v1/tasks/<uuid> - PUT
|
* ../v1/tasks/<uuid> - PUT
|
||||||
* Update a task and retrigger pre_approve.
|
* Update a task and retrigger pre_approve.
|
||||||
* ../v1/tasks/<uuid> - POST
|
* ../v1/tasks/<uuid> - POST
|
||||||
* approve a task
|
* approve a task
|
||||||
* ../v1/token - GET
|
* ../v1/token - GET
|
||||||
* A json containing all tokens.
|
* A json containing all tokens.
|
||||||
* This will be updated to take parameters to refine the list.
|
* Can also be filtered.
|
||||||
* ../v1/token - POST
|
* ../v1/token - POST
|
||||||
* Reissue tokens for a given task.
|
* Reissue tokens for a given task.
|
||||||
* ../v1/token - DELETE
|
* ../v1/token - DELETE
|
||||||
* Delete all expired tokens.
|
* Delete all expired tokens.
|
||||||
* ../v1/token/<uuid> - GET
|
* ../v1/token/<uuid> - GET
|
||||||
* return a json describing the actions and required fields for the token.
|
* return a json describing the actions and required fields for the token.
|
||||||
* ../v1/token/<uuid> - POST
|
* ../v1/token/<uuid> - POST
|
||||||
* submit the token.
|
* submit the token.
|
||||||
* ../v1/notification - GET
|
* ../v1/notification - GET
|
||||||
* Get a list of all unacknowledged notifications.
|
* Get a list of all unacknowledged notifications.
|
||||||
|
* Can also be filtered.
|
||||||
* ../v1/notification - POST
|
* ../v1/notification - POST
|
||||||
* Acknowledge a list of notifications.
|
* Acknowledge a list of notifications.
|
||||||
* ../v1/notification/<id> - GET
|
* ../v1/notification/<id> - GET
|
||||||
* Details on a specific notification.
|
* Details on a specific notification.
|
||||||
* ../v1/notification/<id> - POST
|
* ../v1/notification/<id> - POST
|
||||||
* Acknowledge a specific notification.
|
* Acknowledge a specific notification.
|
||||||
|
|
||||||
##### Filtering Tasks, Tokens, and Notifications
|
##### Filtering Tasks, Tokens, and Notifications
|
||||||
|
|
||||||
@ -87,76 +88,95 @@ Example:
|
|||||||
{'filters': {'task_id': { 'exact': '842433bb-fa08-4fc1-8c3b-aa9904ceb370'}}
|
{'filters': {'task_id': { 'exact': '842433bb-fa08-4fc1-8c3b-aa9904ceb370'}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This looks a bit messy in the url as that json ends up being url-safe encoded, but doing the filters this way gives us a fairly large amount of flexibility.
|
||||||
|
|
||||||
Possible field lookup operations:
|
Possible field lookup operations:
|
||||||
https://docs.djangoproject.com/en/1.8/ref/models/querysets/#id4
|
https://docs.djangoproject.com/en/1.8/ref/models/querysets/#id4
|
||||||
|
|
||||||
#### Default TaskView Endpoints:
|
|
||||||
|
|
||||||
Basic default endpoints for the TaskViews.
|
|
||||||
|
|
||||||
* ../v1/actions/CreateProject - GET
|
|
||||||
* return a json describing the actions and required fields for the endpoint.
|
|
||||||
* ../v1/actions/CreateProject - POST
|
|
||||||
* unauthenticated endpoint
|
|
||||||
* for signup of new users/projects.
|
|
||||||
* task requires manual approval, sends a uri+token for password setup after the project is created and setup.
|
|
||||||
* create project
|
|
||||||
* add admin user to project
|
|
||||||
* setup basic networking if needed
|
|
||||||
* create user on password submit
|
|
||||||
* ../v1/actions/InviteUser - GET
|
|
||||||
* return a json describing the actions and required fields for the endpoint.
|
|
||||||
* ../v1/actions/InviteUser - POST
|
|
||||||
* authenticated endpoint limited by role
|
|
||||||
* auto-approved
|
|
||||||
* add/invite a user to your project
|
|
||||||
* adds an existing user with the selected role, or if non-existent user sends a uri+token to them for setup user before adding the role.
|
|
||||||
* allows adding of users to own project without needing an admin role
|
|
||||||
* ../v1/actions/EditUser - GET
|
|
||||||
* return a json describing the actions and required fields for the endpoint.
|
|
||||||
* also returns a list of users that can be edited on your project.
|
|
||||||
* ../v1/actions/EditUser - POST
|
|
||||||
* authenticated endpoint limited by role
|
|
||||||
* auto-approved
|
|
||||||
* add/remove roles from a user on your project
|
|
||||||
* ../v1/actions/ResetPassword - GET
|
|
||||||
* return a json describing the actions and required fields for the endpoint.
|
|
||||||
* ../v1/actions/ResetPassword - POST
|
|
||||||
* unauthenticated endpoint
|
|
||||||
* auto-approved
|
|
||||||
* issue a uri+token to user email to reset password
|
|
||||||
* ../v1/actions/UpdateEmail - GET
|
|
||||||
* return a json describing the actions and required fields for the endpoint.
|
|
||||||
* ../v1/actions/UpdateEmail - POST
|
|
||||||
* Authenticated but open to any user
|
|
||||||
* auto-approved
|
|
||||||
* takes an email address
|
|
||||||
* issue a uri+token to new email to update to that email
|
|
||||||
|
|
||||||
|
|
||||||
#### OpenStack Style TaskView Endpoints:
|
#### OpenStack Style TaskView Endpoints:
|
||||||
|
|
||||||
For ease of integration with OpenStack, these endpoints are setup to work and partly mimic the way similar ones would work in Keystone. They work and use the TaskViews, with some specical changes for certain required endpoints.
|
For ease of integration with OpenStack, these endpoints are setup to work and partly mimic the way similar ones would work in Keystone. They work and use the TaskViews, with some specical changes for certain required endpoints.
|
||||||
|
|
||||||
* ../v1/openstack/users - GET
|
* ../v1/openstack/users - GET
|
||||||
* Returns a list of users on your project, and their roles.
|
* Returns a list of users on your project, and their roles.
|
||||||
* Also returns a list of pending user invites.
|
* Also returns a list of pending user invites.
|
||||||
* ../v1/openstack/users - POST
|
* ../v1/openstack/users - POST
|
||||||
* See above, same as ../v1/actions/InviteUser - POST
|
* authenticated endpoint limited by role
|
||||||
|
* auto-approved
|
||||||
|
* add/invite a user to your project
|
||||||
|
* adds an existing user with the selected role, or if non-existent user sends a uri+token to them for setup user before adding the role.
|
||||||
|
* allows adding of users to own project without needing an admin role
|
||||||
* ../v1/openstack/users/<user_id> - GET
|
* ../v1/openstack/users/<user_id> - GET
|
||||||
* Get details on the given user, including their roles on your project.
|
* Get details on the given user, including their roles on your project.
|
||||||
* ../v1/openstack/users/<user_id> - DELETE
|
* ../v1/openstack/users/<user_id> - DELETE
|
||||||
* Used to cancel a pending user invite.
|
* Used to cancel a pending user invite.
|
||||||
* ../v1/openstack/users/<user_id>/roles - GET
|
* ../v1/openstack/users/<user_id>/roles - GET
|
||||||
* Returns a list of roles for the user on your project.
|
* Returns a list of roles for the user on your project.
|
||||||
* ../v1/openstack/users/<user_id>/roles - PUT
|
* ../v1/openstack/users/<user_id>/roles - PUT
|
||||||
* Add roles to a user.
|
* Add roles to a user.
|
||||||
* ../v1/openstack/users/<user_id>/roles - DELETE
|
* ../v1/openstack/users/<user_id>/roles - DELETE
|
||||||
* Remove roles from a user.
|
* Remove roles from a user.
|
||||||
* ../v1/openstack/roles - GET
|
* ../v1/openstack/roles - GET
|
||||||
* Returns a list of roles you are allowed to edit on your project.
|
* Returns a list of roles you are allowed to edit on your project.
|
||||||
* ../v1/openstack/forgotpassword - POST
|
* ../v1/openstack/forgotpassword - POST
|
||||||
* Submit a username/email to have a password reset token emailed to it.
|
* Submit a username/email to have a password reset token emailed to it.
|
||||||
|
* ../v1/openstack/email-update - POST
|
||||||
|
* Submit a new email address for your user.
|
||||||
|
* Will notifiy old email address, and send a uri+token to new email to confirm.
|
||||||
|
* On confirm will update email (or username if username is email)
|
||||||
|
* ../v1/openstack/sign-up - POST
|
||||||
|
* unauthenticated endpoint
|
||||||
|
* for signup of new users/projects.
|
||||||
|
* task requires manual approval, sends a uri+token for password setup after the project is created and setup.
|
||||||
|
* create project
|
||||||
|
* setup basic networking if needed
|
||||||
|
* create user with random password
|
||||||
|
* set user given password on token submit
|
||||||
|
|
||||||
|
|
||||||
|
#### (DEPRECATED) Default TaskView Endpoints:
|
||||||
|
|
||||||
|
Basic default endpoints for the TaskViews. These are still mostly used for testing, but are not really for production use. We will be getting rid of them eventually, although they do currently serve as a good basis for some of the more complex views.
|
||||||
|
|
||||||
|
* ../v1/actions/CreateProject - GET
|
||||||
|
* return a json describing the actions and required fields for the endpoint.
|
||||||
|
* ../v1/actions/CreateProject - POST
|
||||||
|
* unauthenticated endpoint
|
||||||
|
* for signup of new users/projects.
|
||||||
|
* task requires manual approval, sends a uri+token for password setup after the project is created and setup.
|
||||||
|
* create project
|
||||||
|
* setup basic networking if needed
|
||||||
|
* create user with random password
|
||||||
|
* set user given password on token submit
|
||||||
|
* ../v1/actions/InviteUser - GET
|
||||||
|
* return a json describing the actions and required fields for the endpoint.
|
||||||
|
* ../v1/actions/InviteUser - POST
|
||||||
|
* authenticated endpoint limited by role
|
||||||
|
* auto-approved
|
||||||
|
* add/invite a user to your project
|
||||||
|
* adds an existing user with the selected role, or if non-existent user sends a uri+token to them for setup user before adding the role.
|
||||||
|
* allows adding of users to own project without needing an admin role
|
||||||
|
* ../v1/actions/EditUser - GET
|
||||||
|
* return a json describing the actions and required fields for the endpoint.
|
||||||
|
* also returns a list of users that can be edited on your project.
|
||||||
|
* ../v1/actions/EditUser - POST
|
||||||
|
* authenticated endpoint limited by role
|
||||||
|
* auto-approved
|
||||||
|
* add/remove roles from a user on your project
|
||||||
|
* ../v1/actions/ResetPassword - GET
|
||||||
|
* return a json describing the actions and required fields for the endpoint.
|
||||||
|
* ../v1/actions/ResetPassword - POST
|
||||||
|
* unauthenticated endpoint
|
||||||
|
* auto-approved
|
||||||
|
* issue a uri+token to user email to reset password
|
||||||
|
* ../v1/actions/UpdateEmail - GET
|
||||||
|
* return a json describing the actions and required fields for the endpoint.
|
||||||
|
* ../v1/actions/UpdateEmail - POST
|
||||||
|
* Authenticated but open to any user
|
||||||
|
* auto-approved
|
||||||
|
* takes an email address
|
||||||
|
* issue a uri+token to new email to update to that email
|
||||||
|
|
||||||
#### More API Documentation:
|
#### More API Documentation:
|
||||||
|
|
||||||
@ -187,7 +207,7 @@ Each action class has the functions "pre_approve", "post_approve", and "submit".
|
|||||||
|
|
||||||
Multiple actions can be chained together under one Task and will execute in the defined order. Actions can pass information along via an in memory cache/field on the task object, but that is only safe for the same stage of execution. Actions can also store data back to the database if their logic requires some info passed along to a later step of execution.
|
Multiple actions can be chained together under one Task and will execute in the defined order. Actions can pass information along via an in memory cache/field on the task object, but that is only safe for the same stage of execution. Actions can also store data back to the database if their logic requires some info passed along to a later step of execution.
|
||||||
|
|
||||||
See **actions.models** for a good idea of Actions.
|
See **actions.models** and **actions.v1** for a good idea of Actions.
|
||||||
|
|
||||||
#### What is a Task?
|
#### What is a Task?
|
||||||
|
|
||||||
@ -207,24 +227,26 @@ TaskViews are classes which extend the base TaskView class and use its imbuilt f
|
|||||||
|
|
||||||
The TaskView will process incoming data and build it into a Task, and the related Action classes.
|
The TaskView will process incoming data and build it into a Task, and the related Action classes.
|
||||||
|
|
||||||
They are very simple to define as the inbuilt functions handle all the real logic, but defining which functions of those are called changes the view to create a task that either requires approval or auto-approves.
|
They are very simple to define as the inbuilt functions handle all the real logic, but defining which functions of those are called changes the view to create a task that either requires approval or auto-approves, with some cases auto-approval coming from the actions themselves if setup to do so.
|
||||||
|
|
||||||
The base TaskView class has three functions:
|
The base TaskView class has three functions:
|
||||||
|
|
||||||
* get
|
* get
|
||||||
* just a basic view function that by default returns list of actions, and their required fields for the action view.
|
* just a basic view function that by default returns list of actions, and their required fields for the action view.
|
||||||
* process_actions
|
* process_actions
|
||||||
* needs to be called in the TaskView definition
|
* needs to be called in the TaskView definition
|
||||||
* A function to run the processing and validation of request data for actions.
|
* A function to run the processing and validation of request data for actions.
|
||||||
* Builds and returns the task object, or the validation errors.
|
* Builds and returns the task object, or the validation errors.
|
||||||
* approve
|
* approve
|
||||||
* Takes a task and approves it, running post_approve actions and issuing a token if needed.
|
* Takes a task and approves it, running post_approve actions and issuing a token if needed.
|
||||||
* Used only if no admin approval is needed for Tasks create by this TaskView.
|
* Used only if no admin approval is needed for Tasks create by this TaskView.
|
||||||
|
|
||||||
See **api.v1.tasks** and look at the TaskView class to get a better idea.
|
See **api.v1.tasks** and look at the TaskView class to get a better idea.
|
||||||
|
|
||||||
For a more complex variant, look at **api.v1.openstack** to see some more unique TaskViews specific to certain endpoints we needed to mimic OpenStack functionality.
|
For a more complex variant, look at **api.v1.openstack** to see some more unique TaskViews specific to certain endpoints we needed to mimic OpenStack functionality.
|
||||||
|
|
||||||
|
In fact, at base these are ApiViews from Django Rest Framework, with some magic built in functions for task processing. You normally will want to pick a HTTP method for your core task itself, but having the other methods return data related to the task, or even trigger slight variants of a task is doable.
|
||||||
|
|
||||||
|
|
||||||
## Development:
|
## Development:
|
||||||
|
|
||||||
@ -234,7 +256,7 @@ While this is a Django application, it does not follow the standard Django folde
|
|||||||
|
|
||||||
Rather than a standard Django application, treat this as a more standard python application in this regard.
|
Rather than a standard Django application, treat this as a more standard python application in this regard.
|
||||||
|
|
||||||
Once installed, all the normal manage.py functions can be called directly on the 'adjutant' commandline function.
|
Once installed, all the normal manage.py functions can be called directly on the 'adjutant-api' commandline function.
|
||||||
|
|
||||||
### Dev Environment:
|
### Dev Environment:
|
||||||
|
|
||||||
@ -256,49 +278,30 @@ $ tox
|
|||||||
```
|
```
|
||||||
To run just action unit tests:
|
To run just action unit tests:
|
||||||
```
|
```
|
||||||
$ tox adjutant.actions
|
$ tox -- adjutant.actions
|
||||||
```
|
```
|
||||||
To run a single api test:
|
To run a single api test:
|
||||||
```
|
```
|
||||||
$ tox adjutant.api.v1.tests.test_api_taskview.TaskViewTests.test_duplicate_tasks_new_user
|
$ tox -- adjutant.api.v1.tests.test_api_taskview.TaskViewTests.test_duplicate_tasks_new_user
|
||||||
```
|
```
|
||||||
|
|
||||||
### Adding Actions:
|
### Adding Actions:
|
||||||
|
|
||||||
Adding new actions is done by creating a new django app in the actions module and defining the action models and their serializers. Action must extend the BaseAction class as defined in the **actions.models** module. They also must add themselves to the global store of actions (see the bottom of existing models modules).
|
Adding new actions is done by creating a new django app in the actions module and defining the action models and their serializers. Action must extend the BaseAction class as defined in the **actions.models.v1.base** module. They also must register themselves to the global store of actions in **action.models**.
|
||||||
|
|
||||||
The documentation for this is mainly inline.
|
The documentation for this is mainly inline.
|
||||||
|
|
||||||
For examples of actions look in: **action.models** and **actions.tenant_setup.models**.
|
For examples of actions look in: **action.models.v1.users**, **action.models.v1.project**, and **action.models.v1.resources**
|
||||||
|
|
||||||
### Adding TaskViews:
|
### Adding TaskViews:
|
||||||
|
|
||||||
Ideally this will be made pluggable in future, but for now requires updating and adding a url entry in api.v1.urls and adding an additional TaskView linked to that url.
|
TaskViews also need to be registered, and then are made active in the conf. To see how to register a TaskView look at **api.v1.models** and in the default conf under **ACTIVE_TASKVIEWS** too see how they are enabled.
|
||||||
|
|
||||||
For examples see the classes CreateProject, InviteUser, and ResetPassword in the **api.v1.tasks** module, and **api.v1.openstack**.
|
For examples see **api.v1.openstack**.
|
||||||
|
|
||||||
|
|
||||||
## Setup/Deployment:
|
## Setup/Deployment:
|
||||||
|
|
||||||
### Debian packaging
|
|
||||||
Debian packaging is done with dh-virtualenv (https://github.com/spotify/dh-virtualenv).
|
|
||||||
When a package is built, a new virtualenv is created and populated using the contents of requirements.txt.
|
|
||||||
|
|
||||||
Package building setup:
|
|
||||||
apt-get install build-essential devscripts dh-virtualenv
|
|
||||||
|
|
||||||
Incrementing package version:
|
|
||||||
'vim setup.py' and increment version parameter.
|
|
||||||
'dch -i' and write release notes, set version.
|
|
||||||
|
|
||||||
Build the package:
|
|
||||||
dpkg-buildpackage -us -uc
|
|
||||||
|
|
||||||
Now a debian package has been built that will unpack a virtualenv containing adjutant and all dependencies in a self-contained package, so they do not conflict with other python packages on the system.
|
|
||||||
|
|
||||||
### Puppet module
|
|
||||||
Then a puppet module will be able to install the debian package, setup a database, and run the service via nginx and uwsgi in the virtualenv.
|
|
||||||
|
|
||||||
### Custom Email Templates
|
### Custom Email Templates
|
||||||
|
|
||||||
Custom email templates are placed in:
|
Custom email templates are placed in:
|
||||||
@ -307,42 +310,48 @@ Custom email templates are placed in:
|
|||||||
```
|
```
|
||||||
This is so that adding personalised or deployment specific templates is kept outside of the scope of the service itself and managed by the deployer.
|
This is so that adding personalised or deployment specific templates is kept outside of the scope of the service itself and managed by the deployer.
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
As Adjutant is built on top of Django, we've used parts of Django's installed apps system to allow us a plugin mechanism that allows additional actions and views to be brought in via external sources. This allows company specific or deployer specific changes to easily live outside of the core service and simply extend the core service where and when need.
|
||||||
|
|
||||||
|
An example of such a plugin is here:
|
||||||
|
https://github.com/catalyst/adjutant-odoo
|
||||||
|
|
||||||
## Future Plans:
|
## Future Plans:
|
||||||
|
|
||||||
Most future plans are around adding additional Actions to the service, but there will be some features that will require some refactoring.
|
Most future plans are around adding additional Actions to the service, but there will be some features that will require some refactoring.
|
||||||
|
|
||||||
While we are presently working with the Keystone V3 API, groups are not being used, but we intend to update the service to also manage and handle user groups. Managing Domains isn't really doable, but having the service be able to accept Domains, and multiple Domain back-ends is being planned.
|
While we are presently working with the Keystone V3 API, groups are not being used, but we intend to update the service to also manage and handle user groups. Managing Domains isn't really doable, but having the service be able to accept Domains, and multiple Domain back-ends is being planned.
|
||||||
|
|
||||||
Additional Actions we wish to add in the near future:
|
Additional Actions and TaskViews we wish to add in the near future:
|
||||||
|
|
||||||
* Update Quota
|
* Update Quota
|
||||||
* Admin is required to do this
|
* Admin is required to do this
|
||||||
* Allows users to request a quota increase and by requiring an admin to simply check, and confirm the request, will make the process faster.
|
* Allows users to request a quota increase and by requiring an admin to simply check, and confirm the request, will make the process faster.
|
||||||
* Makes it effectively a quick 2 step process.
|
* Makes it effectively a quick 2 step process.
|
||||||
* For eventual heirarchical-multi-tenancy this would ideally send these qouta increase requests to the parent for approval.
|
* For eventual heirarchical-multi-tenancy this would ideally send these qouta increase requests to the parent for approval.
|
||||||
|
* Hierarchical Multi-Tenancy in a single domain environment
|
||||||
|
* 'project_admin' to be able to create sub-projects off the current scoped project.
|
||||||
|
* This works as per normal in Keystone but does not require an admin role and enforces a naming convention to ensure unique namespaces per sub-projects and somewhat avoid the project name uniqueness issues per domain.
|
||||||
|
* This also adds inherited role support to the already existing user invite and user role editing features.
|
||||||
|
* some VERY basic sub-project quota (number of sub-projects allowed) via metadata stored on a project in Keystone, with quota calculations in Adjutant checking against number of sub-projects created in your WHOLE tree within given shifting window.
|
||||||
* Stand-alone Setup Network Action + TaskView
|
* Stand-alone Setup Network Action + TaskView
|
||||||
* For users who missed or forgot the step at Project creation, and want a quick network setup.
|
* For users who missed or forgot the step at Project creation, and want a quick network setup.
|
||||||
* Blank Slate
|
* Blank Slate
|
||||||
* Doesn't need admin, and could reuse your own token.
|
* Doesn't need admin, and could reuse your own token.
|
||||||
* Clear my entire project of any and all resources.
|
* Clear my entire project of any and all resources.
|
||||||
* Already doable via the APIs, but would be nice to have it in an easy to request action so clients don't need to code it themselves.
|
* Already doable via the APIs, but would be nice to have it in an easy to request action so clients don't need to code it themselves.
|
||||||
|
* A way to setup and manage MFA credentials for a user
|
||||||
Additional Actions for our own deployment (may be useful to others):
|
* relies on work in Keystone around MFA, and serves only as a means to allow an initial challenge response that requires an initial passcode before MFA would become active for the user in Keystone.
|
||||||
|
|
||||||
* openERP client create
|
|
||||||
* An Action that will create a client in openERP and link them to the Project
|
|
||||||
* Or if the Client already exists, just link them to the project.
|
|
||||||
* Will need to automatically validate that the client doesn't already exist.
|
|
||||||
|
|
||||||
Features that might require a slight refactor:
|
Features that might require a slight refactor:
|
||||||
|
|
||||||
* Break out the TaskViews into a set of explorable endpoints so adding and removing TaskViews is easier.
|
|
||||||
* Add optional serializers for token data.
|
* Add optional serializers for token data.
|
||||||
|
|
||||||
Even less likely, and further far-future additions:
|
Even less likely, and further far-future additions:
|
||||||
|
|
||||||
* Split the system into the api, a queue, and workers. That way tasks are processed asynchronously by the workers.
|
* Split the system into the api, a queue, and workers. That way tasks are processed asynchronously by the workers.
|
||||||
* Will require a bunch of rethinking, but most of the core logic will be reused, with the workers simply waiting for events and executing them on the tasks/actions in much the same way as they are presently.
|
* Will require a bunch of rethinking, but most of the core logic will be reused, with the workers simply waiting for events and executing them on the tasks/actions in much the same way as they are presently.
|
||||||
* Remove concept of predefined action steps entirely, setup Actions to have any possible number of 'steps'.
|
* Remove concept of predefined action steps entirely, setup Actions to have any possible number of 'steps'.
|
||||||
* Will require moving actions to an iterator style pattern with a "next_action" style function as the driving force.
|
* Will require moving actions to an iterator style pattern with a "next_action" style function as the driving force.
|
||||||
* Will alter how chaining actions together works, thus may require a lot of work to define a sensible pattern for chaining them together.
|
* Will alter how chaining actions together works, thus may require a lot of work to define a sensible pattern for chaining them together.
|
||||||
|
@ -365,6 +365,10 @@ class TaskView(APIViewWithLogger):
|
|||||||
return {'notes': ["Task completed successfully."]}, 200
|
return {'notes': ["Task completed successfully."]}, 200
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE(adriant): We should deprecate these TaskViews properly and switch tests
|
||||||
|
# to work against the openstack ones. One option is making these abstract
|
||||||
|
# classes, so we retain the code here, but make them useless without extension.
|
||||||
|
|
||||||
class CreateProject(TaskView):
|
class CreateProject(TaskView):
|
||||||
|
|
||||||
task_type = "create_project"
|
task_type = "create_project"
|
||||||
|
Loading…
Reference in New Issue
Block a user