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

Switch username/password during playbook execution #1386

Merged
merged 3 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 2 additions & 0 deletions changelogs/fragments/relogin-when-username-changes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- httpapi - added ability to switch username/password during playbook execution.
45 changes: 45 additions & 0 deletions plugins/httpapi/zabbix.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@
return None

def login(self, username, password):
# Store username/password in class variables (to be used in "username switch" scenario
self.username = username
self.password = password

self.auth_key = self.get_option('zabbix_auth_key')
if self.auth_key:
self.connection._auth = {'auth': self.auth_key}
Expand Down Expand Up @@ -171,6 +175,47 @@
raise ConnectionError("Invalid JSON response: %s" % value)

if "error" in json_data:
if "re-login" in json_data["error"]["data"]:
# Get this response from Zabbix when we switch username to execute REST API
if not self.auth_key:
# Provide "fake" auth so netcommon.connection does not replace our headers
self.connection._auth = {'auth': 'fake'}

Check warning on line 182 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L182

Added line #L182 was not covered by tests
# Need to login with new username/password
self.login(self.username, self.password)

Check warning on line 184 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L184

Added line #L184 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe instead of caching the password yourself in the httpapi, you could always get the latest versions from the connection objects options:

self.login(self.connection.get_option('remote_user'), self.connection.get_option('password'))

Making the above change to your code seems to make it work for my use-case

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't mind. Let me test and make the change.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Pushed the change, please test.

Copy link
Contributor

Choose a reason for hiding this comment

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

Tested, this works for my use-case!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for testing, merging.

# Replace 'auth' field in payload with new one (we got from login process)
data = json.loads(data)
data['auth'] = self.connection._auth['auth']
data = json.dumps(data)

Check warning on line 188 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L186-L188

Added lines #L186 - L188 were not covered by tests
# Re-send the request we initially were trying to execute
response, response_data = self.connection.send(

Check warning on line 190 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L190

Added line #L190 was not covered by tests
path,
data,
method=request_method,
headers=hdrs
)
value = to_text(response_data.getvalue())

Check warning on line 196 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L196

Added line #L196 was not covered by tests

try:
json_data = json.loads(value) if value else {}

Check warning on line 199 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L198-L199

Added lines #L198 - L199 were not covered by tests
# JSONDecodeError only available on Python 3.5+
except ValueError:
raise ConnectionError("Invalid JSON response: %s" % value)

Check warning on line 202 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L201-L202

Added lines #L201 - L202 were not covered by tests

if "error" in json_data:
raise ConnectionError("REST API returned %s when sending %s" % (json_data["error"], data))

Check warning on line 205 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L205

Added line #L205 was not covered by tests

if "result" in json_data:
json_data = json_data["result"]

Check warning on line 208 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L208

Added line #L208 was not covered by tests

try:

Check warning on line 210 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L210

Added line #L210 was not covered by tests
# Some methods return bool not a dict in "result"
iter(json_data)
except TypeError:

Check warning on line 213 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L212-L213

Added lines #L212 - L213 were not covered by tests
# Do not try to find "error" if it is not a dict
return response.getcode(), json_data

Check warning on line 215 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L215

Added line #L215 was not covered by tests

return response.getcode(), json_data

Check warning on line 217 in plugins/httpapi/zabbix.py

View check run for this annotation

Codecov / codecov/patch

plugins/httpapi/zabbix.py#L217

Added line #L217 was not covered by tests

raise ConnectionError("REST API returned %s when sending %s" % (json_data["error"], data))

if "result" in json_data:
Expand Down