<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
Hello OpenStack Community,<br>
<br>
I'd like to introduce to you all a service we have developed at
Catalyst and are now ready to release to the OpenStack community in
hopes that others may find it useful. As a public cloud provider we
quickly ran into a bunch of little issues around user management,
sign-ups, and other pieces of business logic that needed to fit into
how we administer the cloud but didn't entirely make sense as
additions to existing services. There were also a lot of actions we
wanted to delegate to our customers but couldn't do without giving
them too much power in Keystone, or wanted those actions to send
emails, or extend to external non-OpenStack services.<br>
<br>
Enter Adjutant. Adjutant (previously called StackTask) was built as
a service to allow us to create business workflows that can be
exposed in some fashion over an API. A way for us to build reusable
snippets of code that we can tie together, and a flexible and
pluggable API layer we can expose those on. We needed these to be
able to talk to our external systems, as well as our OpenStack
services, and provide us some basic steps and in some cases the
ability to require approval before an action completes. In many ways
Adjutant also works as a layer around Keystone for us to build
business logic around certain things we'd like our customers to be
able to do in very limited ways.<br>
<br>
The service itself is built on Django with Django-Rest-Framework and
is an API service with the gui component built as a ui plugin for
Horizon that allows easy integration into an OpenStack dashboard.<br>
<br>
Adjutant, as the name implies, is a helper, not a major service, but
one that smooths some situations and an easy place to offload some
admin tasks that a customer or non-admin should be able to trigger
in a more limited way. Not only that, but it stores the history of
all these tasks, who asked for them, and when they were completed.
Anything a user does through Adjutant is stored and able to be
audited, with in future the ability for project admins to be able to
audit their own tasks and see who of their users did something.<br>
<br>
Out of the box it provides the following functionality:
<ul>
<li>User invitation by users with the 'project_admin' or
'project_mod' role.</li>
<ul>
<li>This will send out an email to the person you've invited
with a submission token and let them setup their password and
then grants them roles on your project. If their user exists
already, will only require confirmation and then grant roles.</li>
</ul>
<li>As a 'project_admin' or 'project_mod' you can list the users
with roles on your project and edit their roles or revoke them
from your project.<br>
</li>
<li>Let non-admin users request a password reset.</li>
<ul>
<li>User will be emailed a token which will let them reset their
password.</li>
</ul>
<li>Basic signup</li>
<ul>
<li>Let a user request a new project. Requires admin approval
and will create a new project and user, granting default roles
on the new project. Will reuse existing user if present, or
send an email to the user to setup their password.</li>
</ul>
<li>Let a user update their email address.</li>
<ul>
<li>Will notify old email, and send a confirmation token to the
new.</li>
</ul>
</ul>
Features coming in the future (most either almost done, or in
prototype stages):
<ul>
<li>Forced password reset<br>
</li>
<ul>
<li>users with 'project_admin' or 'project_mod'<b> </b>can
force a password reset for a given user in their projects</li>
<li>cloud admins can force password resets for users on their
cloud.</li>
<li>changes user password to a randomly generated value and
sends user a password reset token to their email.</li>
<li>user must reset before they can log in again.</li>
</ul>
<li>Quota management for your project</li>
<ul>
<li>As a 'project_admin' or 'project_mod' you can request a
change in quota to a set of predefined sizes (as set in the
Adjutant conf). Sizes allows you to increase multiple related
quotas at the same time. You can move to adjacent sizes
without approval a number of times in a configurable window
(days), or an admin can approve your quota change as well.</li>
</ul>
<li>Hierarchical Multi-Tenancy in a single domain environment</li>
<ul>
<li>'project_admin' to be able to create sub-projects off the
current scoped project.</li>
<li>This uses HMT properly in Keystone but does not require an
admin role and enforces a naming convention to ensure unique
namespaces per sub-projects and somewhat avoids the project
name uniqueness issues per domain. It's basically some wrapper
logic for HMT in Keystone.<br>
</li>
<li>This also adds inherited role support to the already
existing user invite and user role editing features.</li>
<li>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. This is mainly to stop sub-projects as a means of
getting around quota limits, and allows admins to approve
sub-projects if beyond what a customer is allowed normally.<br>
</li>
</ul>
<li>Account termination/resource termination</li>
<ul>
<li>Be able to delete/disable a project and all the resources in
it in one go, with some reporting, validation, and
confirmation.<br>
</li>
</ul>
<li>A way to setup and manage MFA credentials for a user</li>
<ul>
<li>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.</li>
<li>and a similar process for deactivating MFA by needing a
passcode.<br>
</li>
<li>with an adjutant-ui panel that displays an SVG QR code.</li>
</ul>
<li>Support for User stores beyond Keystone</li>
<ul>
<li>Allow Adjutant to create/manage users in LDAP/AD as part of
normal user workflows.</li>
<li>This feature was always planned since Keystone does not
support creation/editing when users come from LDAP, so the
existing user store module is mostly an abstraction layer that
can be made pluggable.<br>
</li>
</ul>
</ul>
<br>
Adjutant also supports a simple enough plugin system that lets you
override existing actions and taskviews or build on top of them for
your own deployments or company specific circumstances. This lets
you use the core benefits of the service while keeping your company
specific code in a separate codebase that is easy to integrate.<br>
<br>
The repos will soon be on the OpenStack gerrit, with launchpad for
bug/blueprints, but for now can be found here:<br>
<a class="moz-txt-link-freetext"
href="https://github.com/catalyst/adjutant">https://github.com/catalyst/adjutant</a><br>
<a class="moz-txt-link-freetext"
href="https://github.com/catalyst/adjutant-ui">https://github.com/catalyst/adjutant-ui</a><br>
<a class="moz-txt-link-freetext"
href="https://github.com/catalyst/python-adjutantclient">https://github.com/catalyst/python-adjutantclient</a><br>
<br>
The python client and cli are also on pypi:<br>
<a class="moz-txt-link-freetext"
href="https://pypi.python.org/pypi/python-stacktaskclient">https://pypi.python.org/pypi/python-adjutantclient</a><br>
<br>
And there are existing tempest tests that need to be greatly
expanded (and also renamed):<br>
<a class="moz-txt-link-freetext"
href="https://github.com/catalyst/stacktask-tempest">https://github.com/catalyst/stacktask-tempest</a><br>
<br>
Here is also an example plugin based on how we've integrated this
with our ERP system:<br>
<a class="moz-txt-link-freetext"
href="https://github.com/catalyst/adjutant-odoo">https://github.com/catalyst/adjutant-odoo</a><br>
And to help test the plugin and allow importing of test features
Adjutant itself is also on pypi so plugins can use it as a
requirement for testing:<br>
<a class="moz-txt-link-freetext"
href="https://pypi.python.org/pypi/python-adjutant">https://pypi.python.org/pypi/python-adjutant</a><br>
<br>
<br>
Going forward we're looking for other develops and deployers in the
OpenStack community that are either trying to solve issues that fit
within this service, or need something that this service solves. Let
us pool our resources and make something that can help others avoid
the same pitfalls and development work! There is a lot more we have
planned for the roadmap ranging from larger architectural
improvements, useful features, to minor but useful tweaks. It still
has a bunch of growth and maturity to achieve as a project, but
we're running it in production (an older state at least, with newer
coming soon) and it will only get better in time.<br>
<br>
If this sounds interesting to you, get in touch, try it out, get
involved!<br>
<br>
Cheers,<br>
Adrian Turjak<br>
<br>
</body>
</html>