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

[COST-4407] Add service account support #471

Merged
merged 2 commits into from
Nov 6, 2023
Merged
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
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ OCI_CREDENTIALS=OCI_PRIVATE_KEY
OCI_REGION=OCI_REGION
OCI_BUCKET_NAME=OCI_BUCKET_NAME
OCI_NAMESPACE=OCI_NAMESPACE

HCC_SERVICE_ACCOUNT_ID=SERVICE_ACCOUNT_ID
HCC_SERVICE_ACCOUNT_SECRET=SERVICE_ACCOUNT_SECRET
HCC_TOKEN_URL=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
HCC_TOKEN_SCOPE=api.console
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ The `make run-iqe` command by default will run the smoke tests. However, if you
- `overwrite` will generate a regular report with the invoice id
populated.
1. If `--insights-upload` is specified and pointing to a URL endpoint,
you must have `INSIGHTS_USER` and `INSIGHTS_PASSWORD` set in your
you must have `HCC_SERVICE_ACCOUNT_ID` and `HCC_SERVICE_ACCOUNT_SECRET` set in your
environment. Payloads for insights uploads will be split on a
per-file basis.
1. If `--static-report-file` is used start_date will default to first
Expand Down
2 changes: 1 addition & 1 deletion nise/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = "4.4.6"
__version__ = "4.4.7"

VERSION = __version__.split(".")
10 changes: 7 additions & 3 deletions nise/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,15 +558,19 @@ def _validate_ocp_arguments(parser, options):
elif insights_upload is not None and not os.path.isdir(insights_upload):
insights_user = os.environ.get("INSIGHTS_USER")
insights_password = os.environ.get("INSIGHTS_PASSWORD")
hcc_service_account_id = os.environ.get("HCC_SERVICE_ACCOUNT_ID")
hcc_service_account_secret = os.environ.get("HCC_SERVICE_ACCOUNT_SECRET")
insights_account_id = os.environ.get("INSIGHTS_ACCOUNT_ID")
insights_org_id = os.environ.get("INSIGHTS_ORG_ID")
if (insights_account_id is None or insights_org_id is None) and (
insights_user is None or insights_password is None
if (
(insights_account_id is None or insights_org_id is None)
and (insights_user is None or insights_password is None)
and (hcc_service_account_id is None or hcc_service_account_secret is None)
):
msg = (
f"\n\t--insights-upload {insights_upload} was supplied as an argument\n"
"\tbut this directory does not exist locally. Attempting to upload to Ingress instead, but\n"
"\tthe environment must have \n\t\tINSIGHTS_USER and INSIGHTS_PASSWORD\n\tor\n"
"\tthe environment must have \n\t\\HCC_SERVICE_ACCOUNT_ID and HCC_SERVICE_ACCOUNT_SECRET\n\tor\n"
"\t\tINSIGHTS_ACCOUNT_ID and INSIGHTS_ORG_ID\n\tdefined when attempting an upload to Ingress.\n"
)
msg = msg.format("--insights-upload", insights_upload)
Expand Down
27 changes: 26 additions & 1 deletion nise/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,12 @@ def post_payload_to_ingest_service(insights_upload, local_path):
insights_org_id = os.environ.get("INSIGHTS_ORG_ID")
insights_user = os.environ.get("INSIGHTS_USER")
insights_password = os.environ.get("INSIGHTS_PASSWORD")
hcc_service_account_id = os.environ.get("HCC_SERVICE_ACCOUNT_ID")
hcc_service_account_secret = os.environ.get("HCC_SERVICE_ACCOUNT_SECRET")
hcc_token_url = os.environ.get(
"HCC_TOKEN_URL", "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token"
)
hcc_token_scope = os.environ.get("HCC_TOKEN_SCOPE", "api.console")
content_type = "application/vnd.redhat.hccm.tar+tgz"
if os.path.isfile(local_path):
file_info = os.stat(local_path)
Expand All @@ -306,11 +312,30 @@ def post_payload_to_ingest_service(insights_upload, local_path):
headers=headers,
)

if insights_user and insights_password:
return requests.post(
insights_upload,
data={},
files={"file": ("payload.tar.gz", upload_file, content_type)},
auth=(insights_user, insights_password),
verify=False,
)

headers = {"Content-Type": "application/x-www-form-urlencoded"}
data = f"client_id={hcc_service_account_id}&client_secret={hcc_service_account_secret}"
data += f"&grant_type=client_credentials&scope={hcc_token_scope}"
token_resp = requests.post(hcc_token_url, data=data, headers=headers)
token = None
if token_resp.ok:
token_json = token_resp.json()
token = token_json.get("access_token")

headers = {"Authorization": f"Bearer {token}"}
return requests.post(
insights_upload,
data={},
files={"file": ("payload.tar.gz", upload_file, content_type)},
auth=(insights_user, insights_password),
headers=headers,
verify=False,
)

Expand Down
17 changes: 16 additions & 1 deletion tests/test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ def test_post_payload_to_ingest_service_with_identity_header(self, mock_post):
@patch.dict(os.environ, {"INSIGHTS_USER": "12345", "INSIGHTS_PASSWORD": "54321"})
@patch("nise.report.requests.post")
def test_post_payload_to_ingest_service_with_basic_auth(self, mock_post):
"""Test that the identity header path is taken."""
"""Test that the basic auth path is taken."""
insights_user = os.environ.get("INSIGHTS_USER")
insights_password = os.environ.get("INSIGHTS_PASSWORD")

Expand All @@ -354,6 +354,21 @@ def test_post_payload_to_ingest_service_with_basic_auth(self, mock_post):
self.assertEqual(mock_post.call_args[1].get("auth"), auth)
self.assertNotIn("headers", mock_post.call_args[1])

@patch.dict(os.environ, {"HCC_SERVICE_ACCOUNT_ID": "12345", "HCC_SERVICE_ACCOUNT_SECRET": "54321"})
@patch("nise.report.requests.post")
def test_post_payload_to_ingest_service_with_service_account(self, mock_post):
"""Test that the service account path is taken."""
temp_file = NamedTemporaryFile(mode="w", delete=False)
headers = ["col1", "col2"]
data = [{"col1": "r1c1", "col2": "r1c2"}, {"col1": "r2c1", "col2": "r2c2"}]
_write_csv(temp_file.name, data, headers)

insights_upload = {}
data = {}

post_payload_to_ingest_service(insights_upload, temp_file.name)
self.assertEqual(mock_post.call_args[1].get("data"), data)

def test_defaulting_currency(self):
"""Test that if no currency is provide in options or static it defaults to USD."""
currency = None
Expand Down