@@ -52,22 +52,43 @@ def get_active_plans():
5252 if resp .status_code != 200 :
5353 logging .error ("There is some issue with the channel-info.txt file. Please check https://flatcar.cdn.cncf.io/channel-info.txt" )
5454 logging .error (f"Returned status code: { resp .status_code } " )
55+ return []
5556
5657 plans = [i .split ("=" )[0 ].replace ('_CURRENT' ,'' ).lower () for i in resp .text .strip ().split ('\n ' )]
5758 plans = [plan for plan in plans if plan != 'lts' ]
5859
5960 return plans
6061
6162
63+ def _parse_json_dict (resp , context ):
64+ try :
65+ data = resp .json ()
66+ except Exception as e :
67+ logging .error (
68+ f"Failed to parse JSON response for { context } . Status: { resp .status_code } , Error: { e } "
69+ )
70+ return None
71+
72+ if not isinstance (data , dict ):
73+ logging .error (
74+ f"Unexpected response format for { context } . Status: { resp .status_code } , Response: { resp .text } "
75+ )
76+ return None
77+
78+ return data
79+
80+
6281def generate_partner_center_token (tenant_id , client_id , secret_value ):
6382 data = f"grant_type=client_credentials&client_id={ client_id } &client_secret={ secret_value } &resource=https://graph.microsoft.com"
6483 resp = requests .post (
6584 url = f"https://login.microsoftonline.com/{ tenant_id } /oauth2/token" ,
6685 headers = {"Content-Type" : "application/x-www-form-urlencoded" },
6786 data = data ,
6887 )
69- access_token = resp .json ().get ("access_token" )
70- return access_token
88+ parsed = _parse_json_dict (resp , f"partner center token (tenant '{ tenant_id } ')" )
89+ if not parsed :
90+ return None
91+ return parsed .get ("access_token" )
7192
7293
7394def generate_az_sas_url (plan , version , arch , ** kwargs ):
@@ -118,7 +139,21 @@ def get_product_durable_id(access_token, offer):
118139 headers = {"Authorization" : f"Bearer { access_token } " },
119140 )
120141
121- return resp .json ().get ("value" , [])[0 ].get ("id" )
142+ data = _parse_json_dict (resp , f"product durable ID (offer '{ offer } ')" )
143+ if not data :
144+ return None
145+
146+ values = data .get ("value" , [])
147+ if not values :
148+ logging .error (
149+ f"Failed to fetch product durable ID for offer '{ offer } '. Status: { resp .status_code } , Response: { resp .text } "
150+ )
151+ return None
152+
153+ first_val = values [0 ]
154+ if isinstance (first_val , dict ):
155+ return first_val .get ("id" )
156+ return None
122157
123158
124159def get_plan_durable_id (access_token , product_durable_id , plan ):
@@ -127,7 +162,23 @@ def get_plan_durable_id(access_token, product_durable_id, plan):
127162 headers = {"Authorization" : f"Bearer { access_token } " },
128163 )
129164
130- return resp .json ().get ("value" , [])[0 ].get ("id" )
165+ data = _parse_json_dict (
166+ resp , f"plan durable ID (product '{ product_durable_id } ', plan '{ plan } ')"
167+ )
168+ if not data :
169+ return None
170+
171+ values = data .get ("value" , [])
172+ if not values :
173+ logging .error (
174+ f"Failed to fetch plan durable ID for product '{ product_durable_id } ', plan '{ plan } '. Status: { resp .status_code } , Response: { resp .text } "
175+ )
176+ return None
177+
178+ first_val = values [0 ]
179+ if isinstance (first_val , dict ):
180+ return first_val .get ("id" )
181+ return None
131182
132183
133184def get_image_versions (access_token , product_durable_id , plan_durable_id , corevm = False ):
@@ -140,7 +191,20 @@ def get_image_versions(access_token, product_durable_id, plan_durable_id, corevm
140191 headers = {"Authorization" : f"Bearer { access_token } " },
141192 )
142193
143- return resp .json ().get ("vmImageVersions" )
194+ data = _parse_json_dict (
195+ resp , f"vmImageVersions (product '{ product_durable_id } ', plan '{ plan_durable_id } ')"
196+ )
197+ if not data :
198+ return []
199+
200+ image_versions = data .get ("vmImageVersions" )
201+ if image_versions is None :
202+ logging .warning (
203+ f"No existing vmImageVersions found for product '{ product_durable_id } ', plan '{ plan_durable_id } '."
204+ )
205+ return []
206+
207+ return image_versions
144208
145209
146210def draft_new_image_versions (
@@ -342,7 +406,14 @@ def main():
342406 continue
343407
344408 product_durable_id = get_product_durable_id (access_token , offer )
409+ if not product_durable_id :
410+ logging .error (f"Skipping offer '{ offer } ' due to missing product durable ID." )
411+ continue
412+
345413 plan_durable_id = get_plan_durable_id (access_token , product_durable_id , plan )
414+ if not plan_durable_id :
415+ logging .error (f"Skipping offer '{ offer } ' due to missing plan durable ID." )
416+ continue
346417
347418 product_durable_id = product_durable_id .split ("/" )[1 ]
348419 plan_durable_id = plan_durable_id .split ("/" )[2 ]
0 commit comments