Skip to content

Commit c6de366

Browse files
authored
[ENHANCEMENT] Adding the new feature to remove stale entries based on the # of days
- Adding the new feature to remove stale entries based on the # of days - Changelog updated - Code updated, added some docstring, and removed some commented stuff - Pytest for the inventory menu updated - Version updated
1 parent 30408e0 commit c6de366

File tree

7 files changed

+212
-1
lines changed

7 files changed

+212
-1
lines changed

conf/conf.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
# Current Version
13-
CURRENT_VERSION = "1.10.11"
13+
CURRENT_VERSION = "1.11.12"
1414

1515
# Some file references
1616

@@ -26,6 +26,8 @@
2626
VULNERABILITY_SYSTEMS_FILE = (p / "vulnerability_systems.csv").resolve()
2727
ADVISOR_FILE = (p / "advisor_systems.csv").resolve()
2828

29+
STALE_FILE = (p / "stale_systems_based_on_date.json").resolve()
30+
2931
# TS Info
3032
INV_JSON_FILE = (p / "inventory.json").resolve()
3133
SW_JSON_FILE = (p / "swatch.json").resolve()

docs/changelog.rst

+28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
Changelog
22
---------
33

4+
5+
**v1.11.12 - 01/26/2023**
6+
7+
- [ENHANCEMENT] Adding the new feature to remove stale entries based on the # of days - [`issue 24`_]
8+
- [FIX] Fixing the syspurpose issue - [`issue 168`_]
9+
10+
.. _issue 168: https://github.com/C-RH-C/crhc-cli/issues/168
11+
.. _issue 24: https://github.com/C-RH-C/crhc-cli/issues/24
12+
13+
14+
15+
**v1.10.11 - 08/16/2022**
16+
17+
- [FIX] Ordering the inventory output, avoiding wrong information - [`issue 163`_]
18+
.. _issue 163: https://github.com/C-RH-C/crhc-cli/issues/163
19+
20+
21+
422
**v1.10.10 - 03/25/2022**
523

624
- [ENHANCEMENT] Fixing linters warnings - [`issue 97`_]
@@ -38,6 +56,7 @@ Changelog
3856
.. _issue 134: https://github.com/C-RH-C/crhc-cli/pull/134
3957

4058

59+
4160
**v1.8.8 - 11/06/2021**
4261

4362
- [ENHANCEMENT] Docs updated and Feature page created - [`issue 125`_]
@@ -63,6 +82,7 @@ Changelog
6382
.. _issue 102: https://github.com/C-RH-C/crhc-cli/issues/102
6483

6584

85+
6686
**v1.7.7 - 10/16/2021**
6787

6888
- [ENHANCEMENT] issue_summary_created - [`issue 76`_]
@@ -78,6 +98,7 @@ Changelog
7898
.. _issue 88: https://github.com/C-RH-C/crhc-cli/issues/88
7999

80100

101+
81102
**v1.6.6 - 10/12/2021**
82103

83104
- [ENHANCEMENT] help redesigned and some tests added - [`issue 82`_]
@@ -86,12 +107,15 @@ Changelog
86107
.. _issue 82: https://github.com/C-RH-C/crhc-cli/issues/82
87108

88109

110+
89111
**v1.5.6 - 10/03/2021**
90112

91113
- [FIX] Fixed the correct # of pages and servers - [`issue 78`_]
92114

93115
.. _issue 78: https://github.com/C-RH-C/crhc-cli/issues/78
94116

117+
118+
95119
**v1.5.5 - 10/02/2021**
96120

97121
- [ENHANCEMENT] Stale fields added - [`issue 68`_]
@@ -111,12 +135,14 @@ Changelog
111135
.. _issue 59: https://github.com/C-RH-C/crhc-cli/issues/59
112136

113137

138+
114139
**v1.4.4 - 09/23/2021**
115140

116141
- [FIX] Fixing the error caused by an empty conf file
117142
- [FIX] fixing a minor typo that is causing keyerror issue for the inventory list - short version
118143

119144

145+
120146
**v1.4.3 - 09/11/2021**
121147

122148
- [ENHANCEMENT] Adding the troubleshooting feature - dump json files for inventory
@@ -145,6 +171,7 @@ Changelog
145171
- [FEATURE] Authentication using Token
146172

147173

174+
148175
**v1.1.0 08/25/2021**
149176

150177
- [RFE] remove the sort keys in the JSON output
@@ -154,6 +181,7 @@ Changelog
154181
- [FEATURE] Way to query the API endpoint directly
155182

156183

184+
157185
**v1.0.0 - 08/07/2021**
158186

159187
- Initial idea and first piece of code! :)

execution/execution.py

+141
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import os
1414
import time
1515
import requests
16+
import datetime
17+
from report import report
1618
from credential import token
1719
from conf import conf
1820

@@ -34,6 +36,21 @@ def connection_request(url):
3436
return response
3537

3638

39+
def connection_request_delete(url):
40+
"""
41+
Definition responsible to receive the url, call it and send back the
42+
response, updating the token whenever necessary.
43+
"""
44+
45+
access_token = token.get_token()
46+
response = requests.delete(
47+
url, headers={"Authorization": "Bearer {}".format(access_token)}
48+
)
49+
50+
return response
51+
52+
53+
3754
def check_authentication(response=None):
3855
"""
3956
Check if the current credential is valid and authenticating, if not, will
@@ -182,6 +199,63 @@ def inventory_list_all():
182199
return inventory_full_detail
183200

184201

202+
def inventory_list_all_no_system_profile():
203+
"""
204+
This def will collect all the HBI entries. This call will be pretty quick
205+
once we are not consulting the system_profile endpoint, just the host one.
206+
"""
207+
208+
url = "https://console.redhat.com/api/inventory/v1/hosts?per_page=1"
209+
response = connection_request(url)
210+
check_authentication(response)
211+
212+
# Here we are checking the total number of objects and setting the correct
213+
# number of pages based on that.
214+
# check_response = divmod(response.json()['total'], 50)
215+
# ITEMS_PER_PAGE = 10
216+
check_response = divmod(response.json()["total"], conf.ITEMS_PER_PAGE)
217+
218+
if check_response[1] == 0:
219+
num_of_pages = check_response[0] + 1
220+
else:
221+
num_of_pages = check_response[0] + 2
222+
223+
list_of_servers = []
224+
inventory_full_detail = {"results": "", "total": response.json()["total"]}
225+
inventory_full_detail["results"] = list_of_servers
226+
227+
stage_list = []
228+
stage_dic = {"server": stage_list}
229+
230+
# For debugin purposes
231+
# num_of_pages = 2
232+
233+
for page in range(1, num_of_pages):
234+
url = (
235+
"https://console.redhat.com/api/inventory/v1/hosts?per_page="
236+
+ str(conf.ITEMS_PER_PAGE)
237+
+ "&page="
238+
+ str(page)
239+
+ "&order_by=display_name"
240+
)
241+
response = connection_request(url)
242+
243+
# debug
244+
# print("page # {}".format(page))
245+
246+
for server in response.json()["results"]:
247+
248+
try:
249+
stage_dic["server"] = server
250+
except json.decoder.JSONDecodeError:
251+
stage_dic["server"] = {}
252+
253+
list_of_servers.append(stage_dic)
254+
stage_dic = {}
255+
256+
return inventory_full_detail
257+
258+
185259
def inventory_list_search_by_name(fqdn):
186260
"""
187261
This def will search the HBI entries by keyword
@@ -230,6 +304,73 @@ def inventory_list_search_by_name(fqdn):
230304
return inventory_full_detail
231305

232306

307+
def inventory_remove_stale(num_of_days):
308+
"""
309+
Def responsible to receive the # of days and check
310+
all the servers currently in console.redhat.com, check the last
311+
update and compare with the current date - num_of_days passed
312+
by the customer.
313+
"""
314+
315+
print("The file with the server list to be removed will be created here: {}".format(conf.STALE_FILE))
316+
# Getting the current date and time
317+
current_date = datetime.datetime.now()
318+
# Calculating the date to be tested and removed before that
319+
date_to_test_and_remove = current_date - datetime.timedelta(days=int(num_of_days))
320+
321+
print("Inside remove stale, # of days: {}".format(num_of_days))
322+
print("Please, wait while checking the information ...")
323+
list_server_with_no_system_profile = inventory_list_all_no_system_profile()
324+
325+
# print("ready to go")
326+
stage_lst = []
327+
328+
for srv in list_server_with_no_system_profile['results']:
329+
srv_last_update = srv['server']['updated'].split("T")[0]
330+
# To convert from string to format type
331+
srv_last_update_time_format = datetime.datetime.strptime(srv_last_update, "%Y-%m-%d")
332+
if srv_last_update_time_format < date_to_test_and_remove:
333+
stage_lst.append(srv)
334+
335+
report.json_stale_systems(stage_lst)
336+
337+
count = len(stage_lst)
338+
print("We got {} entries with date equal or less than {}.".format(count, date_to_test_and_remove.strftime("%Y-%m-%d")))
339+
print("if you wish, you can open a second terminal and double-check the file {} with the complete list of servers that will be removed, before you proceed.".format(conf.STALE_FILE))
340+
opt = input("Would you like to proceed and remove then? (y|Y|n|N): ")
341+
342+
if (opt == "y") or (opt == "Y"):
343+
# print("proceed")
344+
inventory_remove_entry(stage_lst)
345+
elif (opt == "n") or (opt == "N"):
346+
print("Canceling")
347+
else:
348+
print("Invalid option")
349+
350+
# print("ready to go")
351+
352+
353+
def inventory_remove_entry(srv_to_be_removed):
354+
"""
355+
Def responsible to remove the entry from console.redhat.com
356+
"""
357+
# print("we are here to remove the entries")
358+
359+
if len(srv_to_be_removed) == 0:
360+
print("Nothing to remove")
361+
sys.exit()
362+
363+
for srv in srv_to_be_removed:
364+
print("here to check")
365+
srv_uuid = srv['server']['id']
366+
last_update = srv['server']['updated']
367+
# srv_uuid = "1784587a-a502-4b98-97ea-634e92e882e2"
368+
url = ("https://console.redhat.com/api/inventory/v1/hosts/" + srv_uuid)
369+
print("Removing .: {}, last update at: {}".format(url, last_update))
370+
response = connection_request_delete(url)
371+
check_authentication(response)
372+
373+
233374
def swatch_list():
234375
"""
235376
This def will collect the first 100 entries from Subscription Watch

help/help_opt.py

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def help_inventory_menu():
4747
list List the inventory entries, first 50\n\
4848
list_all List all the inventory entries\n\
4949
display_name Please, type the FQDN or Partial Hostname\n\
50+
remove_stale Remove all the stale entries based on the # of days\n\
5051
\n\
5152
Flags: \n\
5253
--csv This will generate the output in CSV format. By default, it will be JSON.\

parse/parse.py

+24
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,27 @@ def inventory_sub_menu():
7272
# print("Error: {}".format(e))
7373
...
7474

75+
# To print in JSON format
76+
try:
77+
if (sys.argv[1] == "inventory") and (sys.argv[2] == "remove_stale"):
78+
# execution.inventory_list()
79+
# response = execution.inventory_list()
80+
# print(response)
81+
# print(json.dumps(response, indent=4))
82+
num_of_days=input("Please, type the # of days with no updates. 0 for today, 1 for yesteday, 2 for 2 days ago ...: ")
83+
if num_of_days.isdigit():
84+
pass
85+
else:
86+
print("invalid entry, exiting")
87+
sys.exit()
88+
response = execution.inventory_remove_stale(num_of_days)
89+
# print("end here")
90+
sys.exit()
91+
except IndexError as e:
92+
# print("Error: {}".format(e))
93+
...
94+
95+
7596
# To print in JSON format
7697
if len(sys.argv) == 4 and (sys.argv[2]) == "display_name":
7798
try:
@@ -175,6 +196,9 @@ def inventory_sub_menu():
175196
...
176197

177198

199+
200+
201+
178202
def swatch_sub_menu():
179203
"""
180204
The Subscription Watch sub menu

report/report.py

+14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# from os import write
77
import csv
88
import os
9+
import json
910
from conf import conf
1011

1112

@@ -1616,3 +1617,16 @@ def csv_report_advisor(json_obj):
16161617
writer.writerows(report_list)
16171618

16181619
print("File {} created".format(conf.ADVISOR_FILE))
1620+
1621+
1622+
1623+
def json_stale_systems(stale_srv_list):
1624+
"""
1625+
Responsible for write down the entries that will be removed. Note,
1626+
it will be in JSON format.
1627+
"""
1628+
# print("inside the report")
1629+
# print(json.dumps(stale_srv_list, indent=4))
1630+
1631+
with open(conf.STALE_FILE, "w") as file_obj:
1632+
file_obj.write(json.dumps(stale_srv_list, indent=4))

tests/test_help.py

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def test_check_inventory_help_menu():
4949
list List the inventory entries, first 50\n\
5050
list_all List all the inventory entries\n\
5151
display_name Please, type the FQDN or Partial Hostname\n\
52+
remove_stale Remove all the stale entries based on the # of days\n\
5253
\n\
5354
Flags: \n\
5455
--csv This will generate the output in CSV format. By default, it will be JSON.\

0 commit comments

Comments
 (0)