===============
POP-CREATE-IDEM
===============

First, install `pop-create-idem` this is an extension of `pop-create` that
is designed to easily create boilerplate code for idem-cloud projects.

.. code-block:: bash

    pip3 install pop-create-idem

You now have access to the `pop-create` command with the `idem-cloud` subcommand.

To create a new idem-cloud project, run:

.. code-block:: bash

    pop-create idem-cloud --directory /path/to/new/project --project-name=idem-{my_cloud} --simple-cloud-name={my_cloud}

A new project will have been created with all the boilerplate code needed to get started with idem-cloud:
The directory tree should now look something like this::

    .
    ├── build.conf
    ├── cicd
    │   └── upload-code-coverage.sh
    ├── {project_name}
    │   ├── acct
    │   │   ├── contracts
    │   │   └── {simple_service_name}
    │   │       └── basic_auth.py
    │   ├── conf.py
    │   ├── exec
    │   │   ├── contracts
    │   │   └── {simple_service_name}
    │   │       └── init.py
    │   ├── states
    │   │   ├── contracts
    │   │   └── {simple_service_name}
    │   │       └── init.py
    │   ├── tool
    │   │   └── contracts
    │   └── version.py
    ├── LICENSE
    ├── noxfile.py
    ├── README.rst
    ├── requirements
    │   ├── base.txt
    │   └── tests.in
    ├── setup.py
    └── tests
        ├── __init__.py
        ├── integration
        │   ├── acct
        │   ├── conftest.py
        │   ├── exec
        │   ├── __init__.py
        │   ├── states
        │   └── tool
        └── unit
            ├── acct
            ├── conftest.py
            ├── exec
            ├── __init__.py
            ├── states
            └── tool


Installation
============

Install your new project with pip, it needs to be added to the python environment.

.. code-block:: bash

    pip install -e {project_root}

After installation the new Idem Cloud Provider execution and state modules will be accessible to the pop `hub`.

You can verify with pop-tree. Pop-tree shows you what is on the hub.
Exec --add -sub idem is saying I want shows the exec sub, and add idem to the hub
before I show exec modules; because pop-tree needs to be aware of what's on the
hub before it can show you anything.

.. code-block:: bash

    pip install pop-tree

    # Show the exec modules that properly app-merged onto the hub
    pop-tree exec --add-sub idem

output::

    exec:
    ----------
    {simple_service_name}:
        ----------
        init:
            |_
            |_
    test:
        |_
          - ctx
          - ping
        |_


Authenticating with idem-cloud
==============================

No matter what you use for your authentication method,
in the end they all need to be interchangeable when we are calling exec modules.
For example, let's say I want all my plugins to authenticate with aiohttp,
but I want one plugin to handle username and password authentication,
and I want to make another plugin that handles authentication with an api token.
Under the hood they're both creating an aiohttp session, but they're using credentials
in different ways.

Or maybe we want to have an account plugin that authenticates with a cookie, and that's
a completely different way of using an aiohttp session, but on the back end it's the same,
and it will be the same to exec modules, that are calling the api methods. You could use
a plain request library or httpx, or something else. Account plugins is where you can
handle all those differences, and have different ways of authenticating.

That's the reason you'd want different account plugins;
for different ways of authenticating to the same service.

In idem aws we're using different account plugins, because you can authenticate with
gsuite, iamroles, raw botocore; you can get your credentials from the command line
awscli. You can get aws credentials so many different ways, but under the hood, all
the account plugins for idem-aws end up creating a boto core session.

Keep that in mind with whatever your cloud is. You can make as many plugins to
authenticate as you need; and on the backend they need to create the same interface for
exec modules to interact with.

Edit the file at {project_name}/acct/{simple_cloud_name}/basic_auth.py
This is where you can customize authentication to your cloud.
You can create other plugins in this directory that authenticate in different ways to the same cloud.

After installing idem with pip;
acct, exec, and state modules will be accessible to the pop `hub`.
In order to use them we need to set up our credentials.

Create a new file called `credentials.yaml`, appropriately named, as you populate it with credentials.
The "default" profile will be used automatically by `idem` unless you specify one with `--acct-profile=profile_name` on the idem cli.

There are many ways providers/profiles can be stored. See `acct backends <https://gitlab.com/saltstack/pop/acct-backends>`_
for more information.

This is an example of what is looks like;
This is the file name:

credentials.yaml

And these are the contents of the file:


.. code-block:: sls

    {simple_service_name}.basic_auth:
      default:
        username: my_user
        password: my_pass


Now encrypt the credentials file and add the encryption key and encrypted file path
to the ENVIRONMENT.

The `acct` command should be available as it is a requisite of `idem`.

This is an example of how to encrypt the credential file.

.. code:: bash

    acct encrypt credentials.yaml

output::

    -A9ZkiCSOjWYG_lbGmmkVh4jKLFDyOFH4e4S1HNtNwI=

This is how you add these to your environment;
Use a variable assigned to the value of the output,
and second variable assigned to value of the path to the encrypted fernet file.

.. code:: bash

    export ACCT_KEY="-A9ZkiCSOjWYG_lbGmmkVh4jKLFDyOFH4e4S1HNtNwI="
    export ACCT_FILE=$PWD/credentials.yaml.fernet

Idem will now be able to read these credentials for authentication to your cloud!

Exec modules
============

functions placed in `{project_name}/exec/{simple_service_name}/` will appear on the hub under.
`hub.exec.{simple_service_name}.*`.  The directory structure under `exec` is arbitrary to idem, so use it to keep your
functions organized.  Do NOT put all your functions in one giant file.  That is not very pop.

The directory structure affects where functions are placed on the hub, and how they are referenced on the CLI.

If you create a function called `get` in `{project_name}/exec/{simple_service_name}/instance`,
it can be called from the hub within code like so:

.. code-block:: python

    hub.exec.simple_service_name.instance.get("instance_name")

It could be called from the idem cli like this:

.. code-block:: bash

    idem exec {simple_service_name}.instance.get instance_name

The profile you want to use from your encrypted credentials file can be specified on the command line when calling an exec module directly.
The default is to use the profile named "default".

.. code:: bash

    idem exec --acct-profile my-staging-env {simple_service_name}.instance.list

States
======

A profile can be specified for use with a specific state.
If no profile is specified, the profile called "default", if one exists, will be used:

.. code:: sls

    ensure_user_exists:
      {simple_service_name}.user.present:
        - acct_profile: my-staging-env
        - name: a_user_name
        - kwarg1: val1

It can also be specified from the command line when executing states.

.. code:: bash

    idem state --acct-profile my-staging-env my_state.sls
