<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>