data_renewal_generate.py (6248B)
1 #!/usr/bin/env python3 2 # This Source Code Form is subject to the terms of the Mozilla Public 3 # License, v. 2.0. If a copy of the MPL was not distributed with this 4 # file, You can obtain one at https://mozilla.org/MPL/2.0/. 5 6 """ 7 A script to help generate telemetry renewal csv and request template. 8 This script also modifies metrics.yaml to mark soon to expired telemetry entries. 9 """ 10 11 import csv 12 import json 13 import os 14 import sys 15 16 import yaml 17 from yaml.loader import FullLoader 18 19 METRICS_FILENAME = "../app/metrics.yaml" 20 NEW_METRICS_FILENAME = "../app/metrics_new.yaml" 21 GLEAN_DICTIONARY_PREFIX = ( 22 "https://dictionary.telemetry.mozilla.org/apps/focus_android/metrics/" 23 ) 24 25 # This is to make sure we only write headers for the csv file once 26 write_header = True 27 # The number of soon to expired telemetry detected 28 total_count = 0 29 30 USAGE = """usage: ./{script_name} future_fenix_version_number""" 31 32 # list of values that we care about 33 _KEY_FILTER = [ 34 "type", 35 "description", 36 "bugs", 37 "data_reviews", 38 "expires", 39 ] 40 41 42 def response(last_key, content, expire_version, writer, renewal): 43 global write_header 44 global total_count 45 for key, value in content.items(): 46 if key in {"$schema", "no_lint"}: 47 continue 48 if key == "disabled": 49 continue 50 51 if ("expires" in value) and ( 52 (value["expires"] == "never") or (not value["expires"] <= expire_version) 53 ): 54 continue 55 56 if key == "type": 57 remove_keys = [] 58 for key in content.keys(): 59 if key not in _KEY_FILTER: 60 remove_keys.append(key) 61 62 for key in remove_keys: 63 content.pop(key) 64 65 content["bugs"] = content["bugs"][0] 66 content["data_reviews"] = content["data_reviews"][0] 67 total_count += 1 68 69 # name of the telemtry 70 dictionary_url = GLEAN_DICTIONARY_PREFIX + last_key.lstrip(".").replace( 71 ".", "_" 72 ) 73 result = { 74 "#": total_count, 75 "name": last_key.lstrip("."), 76 "glean dictionary": dictionary_url, 77 } 78 result.update(content) 79 80 # add columns for product to fille out, these should always be added at the end 81 result.update({"keep(Y/N)": ""}) 82 result.update({"new expiry version": ""}) 83 result.update({"reason to extend": ""}) 84 85 # output data-renewal request template 86 if write_header: 87 header = result.keys() 88 writer.writerow(header) 89 write_header = False 90 renewal.write("# Request for Data Collection Renewal\n") 91 renewal.write("### Renew for 1 year\n") 92 renewal.write("Total: TBD\n") 93 renewal.write("———\n") 94 95 writer.writerow(result.values()) 96 97 renewal.write("`" + last_key.lstrip(".") + "`:\n") 98 renewal.write( 99 "1) Provide a link to the initial Data Collection Review Request for this collection.\n" 100 ) 101 renewal.write(" - " + content["data_reviews"] + "\n") 102 renewal.write("\n") 103 renewal.write("2) When will this collection now expire?\n") 104 renewal.write(" - TBD\n") 105 renewal.write("\n") 106 renewal.write("3) Why was the initial period of collection insufficient?\n") 107 renewal.write(" - TBD\n") 108 renewal.write("\n") 109 renewal.write("———\n") 110 return 111 112 if type(value) is dict: 113 response(last_key + "." + key, value, expire_version, writer, renewal) 114 115 116 with open(METRICS_FILENAME) as f: 117 try: 118 arg1 = sys.argv[1] 119 except Exception: 120 print("usage is to include argument of the form `100`") 121 sys.exit() 122 123 # parse metrics.yaml to json 124 write_header = True 125 data = yaml.load(f, Loader=FullLoader) 126 json_data = json.dumps(data) 127 content = json.loads(str(json_data)) 128 csv_filename = arg1 + "_expiry_list.csv" 129 renewal_filename = arg1 + "_renewal_request.txt" 130 current_version = int(arg1) 131 132 # remove files created by last run if exists 133 if os.path.exists(csv_filename): 134 print("remove old csv file") 135 os.remove(csv_filename) 136 137 # remove files created by last run if exists 138 if os.path.exists(renewal_filename): 139 print("remove old renewal request template file") 140 os.remove(renewal_filename) 141 142 # remove files created by last run if exists 143 if os.path.exists(NEW_METRICS_FILENAME): 144 print("remove old metrics yaml file") 145 os.remove(NEW_METRICS_FILENAME) 146 147 data_file = open(csv_filename, "w") 148 csv_writer = csv.writer(data_file) 149 renewal_file = open(renewal_filename, "w") 150 151 response("", content, current_version, csv_writer, renewal_file) 152 renewal_file.close() 153 print("Completed") 154 print("Total count: " + str(total_count)) 155 156 # Go through the metrics.yaml file to mark expired telemetry 157 verify_count = 0 158 f.seek(0, 0) 159 data = f.readlines() 160 with open(NEW_METRICS_FILENAME, "w") as f2: 161 for line in data: 162 if line.lstrip(" ").startswith("expires: ") and not ( 163 line.lstrip(" ").startswith("expires: never") 164 ): 165 start_pos = len("expires: ") 166 version = int(line.lstrip(" ")[start_pos:]) 167 if version <= current_version: 168 verify_count += 1 169 f2.writelines( 170 line.rstrip("\n") 171 + " /* TODO <" 172 + str(verify_count) 173 + "> require renewal */\n" 174 ) 175 else: 176 f2.writelines(line) 177 else: 178 f2.writelines(line) 179 f2.close() 180 181 print("\n==============================") 182 if total_count != verify_count: 183 print("!!! Count check failed !!!") 184 else: 185 print("Count check passed") 186 print("==============================") 187 188 os.remove(METRICS_FILENAME) 189 os.rename(NEW_METRICS_FILENAME, METRICS_FILENAME)