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

Pytest verifies and log-in into vault #12378

Merged
merged 3 commits into from
Sep 27, 2023

Conversation

jyejare
Copy link
Member

@jyejare jyejare commented Aug 28, 2023

Pytest session now verifies the vault session first.

  • If the session expired, it takes you to login, and once logged in, it continues to the next step
  • If the session is running, it just continues
  • This only works for local execution and not in CI as CI has AppRole credentials directly!

Pytest STDOUT:

# pytest -s --collect-only tests/foreman/api/test_product.py
2023-09-11 14:02:28 - robottelo - WARNING - Warning! Vault not logged in!
2023-09-11 14:02:28 - robottelo - WARNING - Warning! The browser is about to open for vault OIDC login, close the tab once the sign-in is done!
2023-08-28 17:55:47 - robottelo - WARNING - Dynaconf validation failed, continuing for the sake of unit tests
    certs.cert_file is required in env main
2023-08-28 17:55:47 - robottelo - WARNING - Dynaconf validation failed, continuing for the sake of unit tests
    certs.cert_file is required in env main
=========== test session starts ==============
platform darwin -- Python 3.11.1, pytest-7.4.0, pluggy-1.0.0
Mandatory Requirements Mismatch: tenacity==8.2.3 dynaconf[vault]==3.2.1
Optional Requirements Mismatch: redis==5.0.0 sphinx==7.2.3
To update mismatched requirements, run the pytest command with '--upgrade-required-reqs' OR '--upgrade-all-reqs' option.
.
.
.
.

@jyejare jyejare requested a review from a team as a code owner August 28, 2023 09:22
@jyejare jyejare added 6.11.z Introduced in or relating directly to Satellite 6.11 CherryPick PR needs CherryPick to previous branches 6.12.z Introduced in or relating directly to Satellite 6.12 6.13.z Introduced in or relating directly to Satellite 6.13 6.14.z Introduced in or relating directly to Satellite 6.14 labels Aug 28, 2023
@jyejare jyejare force-pushed the auto_session_vault branch from 4e7ec8d to 7c27fe5 Compare August 28, 2023 10:53
@ogajduse
Copy link
Member

What is the problem that this PR is trying to solve? What would be a typical use of this new plugin?

@jyejare
Copy link
Member Author

jyejare commented Aug 28, 2023

@ogajduse This saves you from getting out of pytest session for vault-login if its not already logged in into the vault by building the vault login facilities in pytest session itself.

So without worrying if the vault session is expired or not do the process by yourself of vault-login (helps new bees / devs where they would be unaware of they had to to login into vault first), you can directly execute pytest session.

Updated the description how the pytest session runs !

Copy link
Collaborator

@Gauravtalreja1 Gauravtalreja1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just a few questions

Comment on lines 13 to 15
re.search(r'\s*#.*VAULT_SECRET_ID_FOR_DYNACONF', envpath.read_text())
and 'VAULT_SECRET_ID_FOR_DYNACONF' not in os.environ
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this wouldn't handle the case where this variables are already set in dotenv?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This handles with the condition re.search(r'\s*#.*VAULT_SECRET_ID_FOR_DYNACONF', envpath.read_text()) , this variable wouldnt be set by Users because this is APPRole credentials.

The make vault-status is the main entity to find the current status of vault session and does not matters whats set in DotEnv.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Gauravtalreja1 The condition is now changed to just verify if VAULT_SECRET_ID_FOR_DYNACONF environment var is set as thats the feasible check as per our CI, Local execution and PR checks!

vstatus = subprocess.run("make vault-status", shell=True, capture_output=True).returncode
if vstatus != 0:
print('Vault token is expired, Logging you in ...')
subprocess.run('make vault-login', shell=True, stdout=subprocess.PIPE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just curious, when vault-login script opens up a browser to authenticate, then how this is going to handle it? and is it going to wait until its ready?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The auth window will open and until we dont authenticate it holds, and finally after authentication it continues !

Copy link
Member

@ogajduse ogajduse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you stay inside Python?
Stack Python -> shell -> make -> Python is a really ugly way to achieve what you want.

pytest_plugins/auto_vault.py Outdated Show resolved Hide resolved
@jyejare jyejare force-pushed the auto_session_vault branch from 7c27fe5 to e2db134 Compare August 30, 2023 09:36
@jyejare
Copy link
Member Author

jyejare commented Aug 30, 2023

@ogajduse I Agree that it's an ugly way to achieve it but then functions in scripts are not made to be importable outside scripts. Hence same applies to vault_login script file. Since they cant we are calling them via make scripts.

We are wrapping on vault CLI utility in vault-login already so we are already following the path of python - Shell and had to repeat the same here with python - make - python - vault.

If we dont want to go this way, we had to externalize the vault function in utils and then use them in both scripting and this plugin.

Comment on lines 13 to 16
if (
re.search(r'\s*#.*VAULT_SECRET_ID_FOR_DYNACONF', envpath.read_text())
and 'VAULT_SECRET_ID_FOR_DYNACONF' not in os.environ
):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please explain why did you construct the condition in this way and how it is supposed to work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This checks if the pytest session is runing locally not in CI. In CI, the value VAULT_SECRET_ID_FOR_DYNACONF is set in env var and hence it does not need to login via OIDC, it logs in using AppRole credentials.

It is less likely the value is directly set in .env file from CI , but could be possible when one have app role creds and executes from local system. When this value is set , we should not run OIDC for vault login.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who requested this feature? I would like to see real people asking for this feature if we plan to merge it into our codebase.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no such ask but this is an enhancement in user experience. Also helps new bees / outside collaborators like DEVs to quickly execute the tests and no need to learn and worry about vault login first!

@omkarkhatavkar omkarkhatavkar changed the title Pytest verifies and logs in into vault Pytest verifies and log-in into vault Aug 31, 2023
@JacobCallahan
Copy link
Member

Something to consider, if we're wanting to run this in every pytest session, is to bring the script logic into robottelo itself. This way we make the functionality here first-class and not offloaded to a script.

Alternatively, if we want to be less hand-holdy, we could log a warning/error informing the user that they need to run the vault-login make command.

@jyejare jyejare force-pushed the auto_session_vault branch 2 times, most recently from 1e92eb9 to f328479 Compare September 11, 2023 08:52
@ogajduse
Copy link
Member

Output that I got from make vault-login:

$ make vault-login
[D 230914 13:58:52 __init__:31] Registered provider AnsibleTower
[D 230914 13:58:52 __init__:36] Registered action workflow for provider AnsibleTower
[D 230914 13:58:52 __init__:36] Registered action job_template for provider AnsibleTower
[D 230914 13:58:52 __init__:36] Registered action template for provider AnsibleTower
[D 230914 13:58:52 __init__:36] Registered action inventory for provider AnsibleTower
[D 230914 13:58:52 __init__:31] Registered provider Container
[D 230914 13:58:52 __init__:36] Registered action container_host for provider Container
[D 230914 13:58:52 __init__:36] Registered action container_app for provider Container
[D 230914 13:58:52 __init__:31] Registered provider TestProvider
[D 230914 13:58:52 __init__:36] Registered action test_action for provider TestProvider
Error looking up token: Error making API request.

URL: GET https://our.vault.server.com:8200/v1/auth/token/lookup-self
Code: 403. Errors:

* permission denied
2023-09-14 13:58:53 - robottelo - WARNING - Warning! The browser is about to open for vault OIDC login, close the tab once the sign-in is done!
Complete the login via your OIDC provider. Launching browser to:

    https://some.auth.server.in.our.internal.network.com/foo


Waiting for OIDC authentication to complete...
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                  Value
---                  -----
token                nopeiamnotgoingtorevealit
token_accessor       iamnotgoingtorevealthisonetoo
token_duration       20m
token_renewable      true
token_policies       ["default"]
identity_policies    ["app-foo-bar"]
policies             ["app-foo-bar" "default"]
token_meta_role      default
Key                  Value
---                  -----
token                nopeiamnotgoingtorevealit
token_accessor       iamnotgoingtorevealthisonetoo
token_duration       10h
token_renewable      true
token_policies       ["default"]
identity_policies    ["app-ro-mna-satqe-hashicorp"]
policies             ["app-ro-mna-satqe-hashicorp" "default"]
token_meta_role      default
Exception ignored in: <function Vault.__del__ at 0x7f0c99f57740>
Traceback (most recent call last):
  File "/home/ogajduse/repos/robottelo/robottelo/utils/vault.py", line 109, in __del__
AttributeError: 'NoneType' object has no attribute 'environ'

Successfully loaded the settings object:

$ python -c 'from robottelo.config import settings'
[D 230914 13:59:19 __init__:31] Registered provider AnsibleTower
[D 230914 13:59:19 __init__:36] Registered action workflow for provider AnsibleTower
[D 230914 13:59:19 __init__:36] Registered action job_template for provider AnsibleTower
[D 230914 13:59:19 __init__:36] Registered action template for provider AnsibleTower
[D 230914 13:59:19 __init__:36] Registered action inventory for provider AnsibleTower
[D 230914 13:59:19 __init__:31] Registered provider Container
[D 230914 13:59:19 __init__:36] Registered action container_host for provider Container
[D 230914 13:59:19 __init__:36] Registered action container_app for provider Container
[D 230914 13:59:19 __init__:31] Registered provider TestProvider
[D 230914 13:59:19 __init__:36] Registered action test_action for provider TestProvider
2023-09-14 13:59:24 - robottelo - WARNING - Dynaconf validation failed, continuing for the sake of unit tests
    vlan_networking.subnet is required in env main
2023-09-14 13:59:24 - robottelo - WARNING - Dynaconf validation failed, continuing for the sake of unit tests
    vlan_networking.subnet is required in env main

And from make vault-logout I got:

$ make vault-logout
[D 230914 14:01:04 __init__:31] Registered provider AnsibleTower
[D 230914 14:01:04 __init__:36] Registered action workflow for provider AnsibleTower
[D 230914 14:01:04 __init__:36] Registered action job_template for provider AnsibleTower
[D 230914 14:01:04 __init__:36] Registered action template for provider AnsibleTower
[D 230914 14:01:04 __init__:36] Registered action inventory for provider AnsibleTower
[D 230914 14:01:04 __init__:31] Registered provider Container
[D 230914 14:01:04 __init__:36] Registered action container_host for provider Container
[D 230914 14:01:04 __init__:36] Registered action container_app for provider Container
[D 230914 14:01:04 __init__:31] Registered provider TestProvider
[D 230914 14:01:04 __init__:36] Registered action test_action for provider TestProvider
Success! Revoked token (if it existed)
Exception ignored in: <function Vault.__del__ at 0x7f031f83b740>
Traceback (most recent call last):
  File "/home/ogajduse/repos/robottelo/robottelo/utils/vault.py", line 109, in __del__
AttributeError: 'NoneType' object has no attribute 'environ'

I must say that I liked the current version more as this new version spits out too much text that the users do not really need to see when they are "just logging in".

@jyejare jyejare force-pushed the auto_session_vault branch 3 times, most recently from 2051a3e to cc0ac14 Compare September 14, 2023 14:02
@jyejare
Copy link
Member Author

jyejare commented Sep 14, 2023

trigger: test-robottelo
pytest: tests/foreman/api/test_product.py

@jyejare
Copy link
Member Author

jyejare commented Sep 15, 2023

@ogajduse Thanks for verifying it locally on your system. Helps great!!

Though it looks good, I would like to :

  1. Hide broker logs from vault output as people wont feel its related.
  2. Fix the destructor exception!

@JacobCallahan
Copy link
Member

@jyejare is this ready or should it be in draft?

@jyejare
Copy link
Member Author

jyejare commented Sep 20, 2023

@JacobCallahan I think I can quickly fix the destructor exception in this PR and hiding logs for broker could be done in a separate follow up PR.

I haven't identified at how do I hide the broker logs yet , and even that should not block us from using this utility !

Rest of the testing looks good already including PRT, local testing, Make testing by @ogajduse etc.

Also the failed tests are not related to this PR !

@JacobCallahan
Copy link
Member

@jyejare one simple option to try is copying the current environment variables, settings broker's log level to info/warn and passing that to subprocess.run via the env argument

@jyejare
Copy link
Member Author

jyejare commented Sep 27, 2023

@JacobCallahan As per our last discussion we should be good to merge this now ?

@JacobCallahan JacobCallahan merged commit 9f5e5da into SatelliteQE:master Sep 27, 2023
5 checks passed
jyejare added a commit to jyejare/robottelo that referenced this pull request Sep 28, 2023
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
jyejare added a commit to jyejare/robottelo that referenced this pull request Sep 28, 2023
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
jyejare added a commit to jyejare/robottelo that referenced this pull request Sep 28, 2023
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
jyejare added a commit to jyejare/robottelo that referenced this pull request Sep 28, 2023
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
jyejare added a commit that referenced this pull request Oct 3, 2023
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
jyejare added a commit that referenced this pull request Oct 3, 2023
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
jyejare added a commit that referenced this pull request Oct 3, 2023
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
Gauravtalreja1 pushed a commit that referenced this pull request Oct 4, 2023
Pytest verifies and log-in into vault (#12378)

* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
Gauravtalreja1 pushed a commit that referenced this pull request Oct 4, 2023
Pytest verifies and log-in into vault (#12378)

* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
Gauravtalreja1 pushed a commit that referenced this pull request Oct 4, 2023
Pytest verifies and log-in into vault (#12378)

* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
damoore044 pushed a commit to damoore044/robottelo that referenced this pull request Oct 4, 2023
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
@lhellebr
Copy link
Contributor

lhellebr commented Oct 5, 2023

This broke local robottelo runs for me. I don't have vault config file and it shouldn't be required, as per docs:

Using Secrets from Vault
^^^^^^^^^^^^^^^^^^^^^^^^

Robottelo is enabled to fetch secrets from Hashicorp Vault via DynaConf at runtime.

To enable the integration:

#. Copy .env.example to .env file for dynaconf settings object to connect with vault
#. Set VAULT_ENABLED_FOR_DYNACONF to true to enable vault integration
#. Set right values for VAULT_URL_FOR_DYNACONF, VAULT_MOUNT_POINT_FOR_DYNACONF and VAULT_PATH_FOR_DYNACONF
#. Run 'make vault-login' to login into vault and to generate and set the OIDC token automatically
#. Edit any conf file from conf/ directory and add the value for setting in as ``@format {this._secret_name_in_vault_}``.
...

But when I run pytest, I get:

Traceback (most recent call last):
  File "/home/lhellebr/git/robottelo/venv/bin/pytest", line 8, in <module>
    sys.exit(console_main())
  File "/home/lhellebr/git/robottelo/venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 192, in console_main
    code = main()
...
File "/home/lhellebr/git/robottelo/pytest_plugins/auto_vault.py", line 9, in pytest_addoption
    with Vault() as vclient:
  File "/home/lhellebr/git/robottelo/robottelo/utils/vault.py", line 110, in __enter__
    self.setup()
  File "/home/lhellebr/git/robottelo/robottelo/utils/vault.py", line 24, in setup
    self.export_vault_addr()
  File "/home/lhellebr/git/robottelo/robottelo/utils/vault.py", line 30, in export_vault_addr
    envdata = self.env_path.read_text()
  File "/usr/lib64/python3.10/pathlib.py", line 1134, in read_text
    with self.open(mode='r', encoding=encoding, errors=errors) as f:
  File "/usr/lib64/python3.10/pathlib.py", line 1119, in open
    return self._accessor.open(self, mode, buffering, encoding, errors,
FileNotFoundError: [Errno 2] No such file or directory: '/home/lhellebr/git/robottelo/.env'

@jyejare
Copy link
Member Author

jyejare commented Oct 5, 2023

@lhellebr PR is raised #12822 to address the issue !

ColeHiggins2 pushed a commit to ColeHiggins2/robottelo that referenced this pull request Oct 9, 2023
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
damoore044 pushed a commit to damoore044/robottelo that referenced this pull request Oct 10, 2023
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
shweta83 pushed a commit to shweta83/robottelo that referenced this pull request Apr 10, 2024
* Pytest verifies and logs in into vault

* New vault lib utils for both

* PR checks without vault login
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.11.z Introduced in or relating directly to Satellite 6.11 6.12.z Introduced in or relating directly to Satellite 6.12 6.13.z Introduced in or relating directly to Satellite 6.13 6.14.z Introduced in or relating directly to Satellite 6.14 CherryPick PR needs CherryPick to previous branches
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants