Skip to content

Commit a19e1ba

Browse files
authored
feat: update insights action plugin to handle oauth (ansible#15742)
1 parent f05173c commit a19e1ba

File tree

2 files changed

+64
-11
lines changed

2 files changed

+64
-11
lines changed

awx/playbooks/action_plugins/insights.py

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import re
77

88
import requests
9+
from urllib.parse import urljoin
910

1011
from ansible.plugins.action import ActionBase
1112

@@ -34,27 +35,73 @@ def write_version(self, proj_path, etag):
3435
with open(file_path, 'w') as f:
3536
f.write(etag)
3637

38+
def _obtain_auth_token(self, oidc_endpoint, client_id, client_secret):
39+
main_url = urljoin(oidc_endpoint, '/.well-known/openid-configuration')
40+
response = requests.get(url=main_url, headers={'Accept': 'application/json'})
41+
data = {}
42+
if response.status_code != 200:
43+
data['failed'] = True
44+
data['msg'] = 'Expected {} to return a status code of 200 but returned status code "{}" instead with content "{}".'.format(
45+
main_url, response.status_code, response.content
46+
)
47+
return data
48+
49+
auth_url = response.json().get('token_endpoint', None)
50+
data = {
51+
'grant_type': 'client_credentials',
52+
'scope': 'api.console',
53+
'client_id': client_id,
54+
'client_secret': client_secret,
55+
}
56+
response = requests.post(url=auth_url, data=data)
57+
58+
if response.status_code != 200:
59+
data['failed'] = True
60+
data['msg'] = 'Expected {} to return a status code of 200 but returned status code "{}" instead with content "{}".'.format(
61+
auth_url, response.status_code, response.content
62+
)
63+
else:
64+
data['token'] = response.json().get('access_token', None)
65+
data['token_type'] = response.json().get('token_type', None)
66+
return data
67+
3768
def run(self, tmp=None, task_vars=None):
3869
self._supports_check_mode = False
3970

71+
session = requests.Session()
4072
result = super(ActionModule, self).run(tmp, task_vars)
4173

4274
insights_url = self._task.args.get('insights_url', None)
43-
username = self._task.args.get('username', None)
44-
password = self._task.args.get('password', None)
4575
proj_path = self._task.args.get('project_path', None)
4676
license = self._task.args.get('awx_license_type', None)
4777
awx_version = self._task.args.get('awx_version', None)
78+
authentication = self._task.args.get('authentication', None)
79+
username = self._task.args.get('username', None)
80+
password = self._task.args.get('password', None)
81+
client_id = self._task.args.get('client_id', None)
82+
client_secret = self._task.args.get('client_secret', None)
83+
oidc_endpoint = self._task.args.get('oidc_endpoint', None)
84+
85+
session.headers.update(
86+
{
87+
'Content-Type': 'application/json',
88+
'User-Agent': '{} {} ({})'.format('AWX' if license == 'open' else 'Red Hat Ansible Automation Platform', awx_version, license),
89+
}
90+
)
91+
92+
if authentication == 'service_account' or (client_id and client_secret):
93+
data = self._obtain_auth_token(oidc_endpoint, client_id, client_secret)
94+
if 'token' not in data:
95+
result['failed'] = data['failed']
96+
result['msg'] = data['msg']
97+
return result
98+
session.headers.update({'Authorization': f'{result['token_type']} {result['token']}'})
99+
elif authentication == 'basic' or (username and password):
100+
session.auth = requests.auth.HTTPBasicAuth(username, password)
48101

49-
session = requests.Session()
50-
session.auth = requests.auth.HTTPBasicAuth(username, password)
51-
headers = {
52-
'Content-Type': 'application/json',
53-
'User-Agent': '{} {} ({})'.format('AWX' if license == 'open' else 'Red Hat Ansible Automation Platform', awx_version, license),
54-
}
55102
url = '/api/remediations/v1/remediations'
56103
while url:
57-
res = session.get('{}{}'.format(insights_url, url), headers=headers, timeout=120)
104+
res = session.get('{}{}'.format(insights_url, url), timeout=120)
58105

59106
if res.status_code != 200:
60107
result['failed'] = True

awx/playbooks/project_update.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
# awx_version: Current running version of the awx or tower as a string
2020
# awx_license_type: "open" for AWX; else presume Tower
2121
# gpg_pubkey: the GPG public key to use for validation, when enabled
22+
# client_id: Red Hat service account client ID; required for the 'service_account' authentication method used against the Insights API
23+
# client_secret: Red Hat service account client secret; required for the 'service_account' authentication method used against the Insights API
24+
# oidc_endpoint: OpenID Connect URL for 'service_account' authentication method.
2225

2326
- hosts: localhost
2427
gather_facts: false
@@ -95,11 +98,14 @@
9598
- name: Fetch Insights Playbook(s)
9699
insights:
97100
insights_url: "{{ insights_url }}"
98-
username: "{{ scm_username }}"
99-
password: "{{ scm_password }}"
101+
username: "{{ scm_username | default(omit) }}"
102+
password: "{{ scm_password | default(omit) }}"
100103
project_path: "{{ project_path }}"
101104
awx_license_type: "{{ awx_license_type }}"
102105
awx_version: "{{ awx_version }}"
106+
client_id: "{{ client_id | default(omit) }}"
107+
client_secret: "{{ client_secret | default(omit) }}"
108+
authentication: "{{ authentication | default(omit) }}"
103109
register: results
104110

105111
- name: Save Insights Version

0 commit comments

Comments
 (0)