Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Adding Support For Environment Variables #684

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions ansible_collections/arista/cvp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,19 @@ ansible_httpapi_port=443

As modules of this collection are based on [`HTTPAPI` connection plugin](https://docs.ansible.com/ansible/latest/plugins/httpapi.html), authentication elements shall be declared using this plugin mechanism and are automatically shared with `arista.cvp.cv_*` modules.

Alternatively, on a play where you are leveraging a plugin you can omit CVP from inventory, set the play to target "localhost" and set the connection requirements using the following environment variables:

CVP_HOST (Example: mycvpserver.prod.example.com)
CVP_PORT (Example: 443)
CVP_USER (Example: myserviceaccount) *
CVP_PASS (Example: mystrongpassword)
CVP_TOKEN (Example: mycvpapitoken)
CVP_CERT_VALIDATE (Example: False)
CVP_CMD_TIMEOUT (Example: 30)
CVP_CON_TIMEOUT (Example: 90)

* Review the CVP Authentication documentation for local service accounts.

## License

The project is published under [Apache License](LICENSE).
Expand Down
49 changes: 42 additions & 7 deletions ansible_collections/arista/cvp/docs/how-to/cvp-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,31 @@ ansible_password: "{{ lookup('file', '/path/to/onprem.token')}}"

### Example reading from an environment variable

The following environment variables are supported for cvp authentication:

CVP_HOST (Example: mycvpserver.prod.example.com)
CVP_PORT (Example: 443)
CVP_USER (Example: myserviceaccount) *
CVP_PASS (Example: mystrongpassword)
CVP_TOKEN (Example: mycvpapitoken)
CVP_CERT_VALIDATE (Example: False)
CVP_CMD_TIMEOUT (Example: 30)
CVP_CON_TIMEOUT (Example: 90)

```shell
export ONPREM_TOKEN=`cat /path/to/onprem.token`
export CVP_USER=svc_account
```

While it is possible to reference an environment variable in host or group vars like so:

```yaml
ansible_user: svc_account
ansible_password: "{{ lookup('env', 'ONPREM_TOKEN')}}"
ansible_password: "{{ lookup('env', 'CVP_TOKEN')}}"
```

> NOTE Both `ansible_ssh_pass` and `ansible_password` can be used to specify the password or the token.
for Ansible Tower (AAPv2) it is not supported to reference templated variables in a sourced inventory. Providing values as environment variables via Custom Credential Types and associating the credentials with an inventory source or template allows you to store values such as the FQDN or Token within Ansible Tower and pass them to plugins.

> NOTE Remove CVP from your inventory and replace any references to it with localhost in plays / tasks that reference it for targeting or delegation if you want to leverage the environment variables.

### Example using vault

Expand Down Expand Up @@ -113,6 +128,7 @@ all:
provide the password with any other methods as described in the [ansible vault documentation](https://docs.ansible.com/ansible/latest/user_guide/vault.html#using-encrypted-variables-and-files).

> NOTE Encrypting individual variables using vault may not be supported - cf notes at the end of ## On-premise CloudVision authentication section
> NOTE This is not supported in Ansible Tower (AAPv2)

## CloudVision as a Service authentication

Expand Down Expand Up @@ -146,20 +162,39 @@ ansible_password: "{{ lookup('file', '/path/to/cvaas.token')}}"

### Example reading from an environment variable

export CVAAS_TOKEN=`cat /path/to/cvaas.token`
The following environment variables are supported for cvp authentication:

CVP_HOST (Example: mycvpserver.prod.example.com)
CVP_PORT (Example: 443)
CVP_USER (Example: myserviceaccount) *
CVP_PASS (Example: mystrongpassword)
CVP_TOKEN (Example: mycvpapitoken)
CVP_CERT_VALIDATE (Example: False)
CVP_CMD_TIMEOUT (Example: 30)
CVP_CON_TIMEOUT (Example: 90)

```shell
export CVP_USER=svc_account
```

While it is possible to reference an environment variable in host or group vars like so:

```yaml
ansible_user: cvaas
ansible_password: "{{ lookup('env', 'CVAAS_TOKEN')}}"
ansible_user: svc_account
ansible_password: "{{ lookup('env', 'CVP_TOKEN')}}"
```

> NOTE Both `ansible_ssh_pass` and `ansible_password` can be used to specify the token.
for Ansible Tower (AAPv2) it is not supported to reference templated variables in a sourced inventory. Providing values as environment variables via Custom Credential Types and associating the credentials with an inventory source or template allows you to store values such as the FQDN or Token within Ansible Tower and pass them to plugins.

> NOTE Remove CVP from your inventory and replace any references to it with localhost in plays / tasks that reference it for targeting or delegation if you want to leverage the environment variables.

### Example using vault

1. Save the token generated from the CV/CVaaS UI and encrypt it using `ansible-vault encrypt cvaas.token`
2. Run the playbook with `ansible-playbook example.yaml --ask-vault-pass`

> NOTE This is not supported in Ansible Tower (AAPv2), refer to previous section.

## How to validate SSL certificate

### Validate SSL cert signed by public CA
Expand Down
59 changes: 47 additions & 12 deletions ansible_collections/arista/cvp/plugins/module_utils/tools_cv.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
__metaclass__ = type
import logging
import traceback
import os
from ansible.module_utils.connection import Connection
try:
from cvprac.cvp_client import CvpClient
Expand All @@ -36,24 +37,58 @@ def cv_connect(module):
Returns
-------
CvpClient
Instanciated CvpClient with connection information.
Instantiated CvpClient with connection information.

ENVIRONMENT VARIABLES
-------
Hosts = CVP_HOST
Port = CVP_PORT
User = CVP_USER
Password = CVP_PASS
Token = CVP_TOKEN
Cert Validation = CVP_CERT_VALIDATE
Command Timeout = CVP_CMD_TIMEOUT
Connection Timeout = CVP_CON_TIMEOUT
"""
client = CvpClient()
LOGGER.info('Connecting to CVP')
connection = Connection(module._socket_path)
# use 'cvaas' user for CVaaS connection and 'svc_account' for CV on-prem using service account token
inventory = False
try:
connection = Connection(module._socket_path)
inventory = True
except(AssertionError):
pass
# Use 'cvaas' user for CVaaS connection and 'svc_account' for CV on-prem using service account token
svc_accounts = ['cvaas', 'svc_account']
host = connection.get_option("host")
port = connection.get_option("port")
cert_validation = connection.get_option("validate_certs")
is_cvaas = True if connection.get_option("remote_user") == 'cvaas' else False
api_token = connection.get_option("password") if connection.get_option("remote_user") in svc_accounts else None
user = connection.get_option("remote_user") if connection.get_option("remote_user") != 'cvaas' else ''
user_authentication = connection.get_option("password") if connection.get_option("remote_user") != 'cvaas' else ''
ansible_command_timeout = connection.get_option(
# Checks if inventory is set or if environment variables are preferred
if inventory:
cvp_user = connection.get_option("remote_user")
cvp_pass = connection.get_option("password")
host = connection.get_option("host")
port = connection.get_option("port")
cert_validation = connection.get_option("validate_certs")
api_token = cvp_pass if cvp_user in svc_accounts else None
ansible_command_timeout = connection.get_option(
"persistent_command_timeout")
ansible_connect_timeout = connection.get_option(
ansible_connect_timeout = connection.get_option(
"persistent_connect_timeout")
else:
cvp_user = os.getenv("CVP_USER")
cvp_pass = os.getenv("CVP_PASS")
host = os.getenv("CVP_HOST")
port = int(os.getenv("CVP_PORT"))
cert_validation = os.getenv("CVP_CERT_VALIDATE")
if cert_validation == "True":
cert_validation = True
elif cert_validation == "False":
cert_validation = False
api_token = os.getenv("CVP_TOKEN")
ansible_command_timeout = int(os.getenv("CVP_CMD_TIMEOUT"))
ansible_connect_timeout = int(os.getenv("CVP_CON_TIMEOUT"))

is_cvaas = True if cvp_user == 'cvaas' else False
user = cvp_user if is_cvaas == False else ''
user_authentication = cvp_pass if is_cvaas == False else ''

# The following is needed because of https://github.com/ansible/ansible/issues/75503
# Which was fixed in https://github.com/ansible/ansible/pull/78236
Expand Down
Loading