Skip to content

Commit

Permalink
Merge pull request #47 from redhatci/deprecated_identify
Browse files Browse the repository at this point in the history
Identify service accounts utilizing deprecated APIs
  • Loading branch information
tkrishtop authored Jun 14, 2024
2 parents 9eaf75a + b64fd9a commit 6383ff9
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 28 deletions.
23 changes: 16 additions & 7 deletions plugins/filter/ocp_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def ocp_compatibility(self, removed_in_release_api, curr_version, junit_ocp_file
Parse the deprecated and to-be-deprecated API after the workload installation.
'''
from junit_xml import TestCase, TestSuite
from collections import defaultdict

def k8s2ocp(k8s_version):
'''
Expand Down Expand Up @@ -36,10 +37,13 @@ def ocp_to_str(version):

# parse the API after the workload installation and write down incompatible OCP versions
failed_versions = {k8s2ocp(api['removedInRelease']) for api in removed_in_release_api}
version_to_removed_apis = {
version: {api['name'] for api in removed_in_release_api if k8s2ocp(api['removedInRelease']) == version}
for version in failed_versions
}
version_to_removed_apis = defaultdict(list)
for api in removed_in_release_api:
release = k8s2ocp(api['removedInRelease'])
name = api['name']
service_accounts = api['serviceAccounts']

version_to_removed_apis[release].append((name, service_accounts))

# Find max version in the set of incompatible versions.
# If the set is empty, bump the current version.
Expand All @@ -51,9 +55,14 @@ def ocp_to_str(version):
status = 'compatible'
while version <= max_version:
if version in failed_versions:
deprecated_apis = ", ".join(version_to_removed_apis[version])
compatibility[version] = status + ", " + deprecated_apis if status != 'compatible' else deprecated_apis
status = deprecated_apis
incompatible_apis = ', '.join(
f"{name} (service accounts: {', '.join(service_accounts)})"
for name, service_accounts in version_to_removed_apis[version]
)
# making sure to carry the incompatible versions
# from the previous releases
compatibility[version] = status + ", " + incompatible_apis if status != 'compatible' else incompatible_apis
status = incompatible_apis
elif status != 'compatible':
compatibility[version] = status
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,39 @@

- name: "Extract deprecated and to-be-deprecated API for {{ da_ns }}"
vars:
query: "resources[*].{name: metadata.name, removedInRelease: status.removedInRelease}[?removedInRelease != null]"
query: >
resources[?status.removedInRelease != null].{
name: metadata.name,
removedInRelease: status.removedInRelease,
serviceAccounts: status.last24h[].byNode[].byUser[].username
}
ansible.builtin.set_fact:
da_removed_api: "{{ deprecated_api_apirequestcount | json_query(query) | flatten | unique }}"
da_removed_api_dupes: "{{ deprecated_api_apirequestcount | json_query(query) }}"

- name: "Reset da_removed_api before processing new namespace {{ da_ns }}"
ansible.builtin.set_fact:
da_removed_api: []

- name: "Remove duplicates from serviceAccounts for {{ da_ns }}"
ansible.builtin.set_fact:
da_removed_api: >-
{{
da_removed_api +
[{
'name': item.name,
'removedInRelease': item.removedInRelease,
'serviceAccounts': item.serviceAccounts | unique
}] | unique(attribute='name')
}}
loop: "{{ da_removed_api_dupes }}"

- name: "Display cleaned API data for {{ da_ns }}"
ansible.builtin.debug:
var: da_removed_api

- name: "Compute OCP compatibility of the workload API for {{ da_ns }}"
vars:
ocp_filename: "{{ deprecated_api_logs.path }}/apirequestcounts_ocp_compatibility_{{ da_ns }}_junit.xml"
set_fact:
ansible.builtin.set_fact:
ocp_compatibility: "{{ da_removed_api | redhatci.ocp.ocp_compatibility(da_ocp_version, ocp_filename) }}"
...
28 changes: 20 additions & 8 deletions tests/unit/data/test_ocp_compatibility_data.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
[
{
"name": "flowschemas.v1beta2.flowcontrol.apiserver.k8s.io",
"removedInRelease": "1.29"
},
{
"name": "prioritylevelconfigurations.v1beta2.flowcontrol.apiserver.k8s.io",
"removedInRelease": "1.29"
}
{
"name": "events.v1beta1.events.k8s.io",
"removedInRelease": "1.25",
"serviceAccounts": ["system:serviceaccount:default:eventtest-operator-service-account"]
},
{
"name": "flowschemas.v1beta1.flowcontrol.apiserver.k8s.io",
"removedInRelease": "1.26",
"serviceAccounts": ["system:serviceaccount:openshift-cluster-version:default"]
},
{
"name": "podsecuritypolicies.v1beta1.policy",
"removedInRelease": "1.25",
"serviceAccounts": ["system:kube-controller-manager"]
},
{
"name": "prioritylevelconfigurations.v1beta1.flowcontrol.apiserver.k8s.io",
"removedInRelease": "1.26",
"serviceAccounts": ["system:serviceaccount:openshift-cluster-version:default"]
}
]
30 changes: 20 additions & 10 deletions tests/unit/filter/test_ocp_compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,34 @@ def test_filter_with_no_deprecated_api_with_empty_array(self):

def test_filter_with_deprecated_api_in_non_empty_list(self):
filter = ocp_compatibility.FilterModule()
json_file_path = os.path.join(os.path.dirname(__file__), '..', 'data', 'test_ocp_compatibility_data.json')
json_file_path = os.path.join(
os.path.dirname(__file__), '..', 'data', 'test_ocp_compatibility_data.json'
)

with open(json_file_path, 'r') as json_file:
json_data = json.load(json_file)

with tempfile.TemporaryDirectory() as tmpdirname:
actual_result = filter.filters()["ocp_compatibility"](
json_data, "4.13", os.path.join(tmpdirname, "junit.xml"))

# The order of elements in a dictionary is not guaranteed in Python.
# Have to sort before comparing to avoid random failures.
actual_result["4.16"] = ", ".join(sorted(actual_result["4.16"].split(", ")))
json_data, "4.11", os.path.join(tmpdirname, "junit.xml")
)

expected_result = {
"4.13": "compatible",
"4.14": "compatible",
"4.15": "compatible",
"4.16": "flowschemas.v1beta2.flowcontrol.apiserver.k8s.io, prioritylevelconfigurations.v1beta2.flowcontrol.apiserver.k8s.io",
"4.11": "compatible",
"4.12": " ".join([
"events.v1beta1.events.k8s.io (service accounts: system:serviceaccount:default:",
"eventtest-operator-service-account), podsecuritypolicies.v1beta1.policy ",
"(service accounts: system:kube-controller-manager)"
]),
"4.13": " ".join([
"events.v1beta1.events.k8s.io (service accounts: system:serviceaccount:default:",
"eventtest-operator-service-account), podsecuritypolicies.v1beta1.policy ",
"(service accounts: system:kube-controller-manager), flowschemas.v1beta1.",
"flowcontrol.apiserver.k8s.io (service accounts: system:serviceaccount:",
"openshift-cluster-version:default), prioritylevelconfigurations.v1beta1.",
"flowcontrol.apiserver.k8s.io (service accounts: system:serviceaccount:",
"openshift-cluster-version:default)"
])
}

self.assertEqual(actual_result, expected_result)
Expand Down

0 comments on commit 6383ff9

Please sign in to comment.