11#!/usr/bin/env python3
22import hashlib
3- import json
43import os
5- import ssl
64import sys
7- import urllib .error
8- import urllib .request
95from datetime import datetime , timezone
106
11- CA_DIR = "/tmp/secrets"
12- HASH_FILE = os .path .join (CA_DIR , ".ca-hash-previous" )
7+ import requests
138
9+ HASH_FILE_NAME = ".ca-hash-previous"
1410
15- def hash_dir (path ):
11+ SA_TOKEN = "/var/run/secrets/kubernetes.io/serviceaccount/token"
12+ SA_CA = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
13+ K8S_API = "https://kubernetes.default.svc"
14+
15+
16+ def hash_file (file_path ):
1617 h = hashlib .sha256 ()
17- for fname in sorted (os .listdir (path )):
18- if fname .startswith ("." ):
19- continue
20- fpath = os .path .join (path , fname )
21- if os .path .isfile (fpath ):
22- with open (fpath , "rb" ) as f :
23- h .update (fname .encode ())
24- h .update (f .read ())
18+ with open (file_path , "rb" ) as f :
19+ h .update (f .read ())
2520 return h .hexdigest ()
2621
2722
2823def trigger_restart (namespace , deployment ):
29- with open ("/var/run/secrets/kubernetes.io/serviceaccount/token" ) as f :
24+ with open (SA_TOKEN ) as f :
3025 token = f .read ()
3126 timestamp = datetime .now (timezone .utc ).strftime ("%Y-%m-%dT%H:%M:%SZ" )
32- body = json .dumps (
33- {
34- "spec" : {
35- "template" : {
36- "metadata" : {
37- "annotations" : {"kubectl.kubernetes.io/restartedAt" : timestamp }
38- }
27+ body = {
28+ "spec" : {
29+ "template" : {
30+ "metadata" : {
31+ "annotations" : {"kubectl.kubernetes.io/restartedAt" : timestamp }
3932 }
4033 }
4134 }
42- ).encode ()
43- ctx = ssl .create_default_context (
44- cafile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
45- )
35+ }
4636 url = (
47- f"https://kubernetes.default.svc /apis/apps/v1"
37+ f"{ K8S_API } /apis/apps/v1"
4838 f"/namespaces/{ namespace } /deployments/{ deployment } "
4939 )
50- req = urllib . request . Request (
40+ response = requests . patch (
5141 url ,
52- data = body ,
53- method = "PATCH" ,
42+ json = body ,
5443 headers = {
55- "Authorization" : "Bearer " + token ,
44+ "Authorization" : f "Bearer { token } " ,
5645 "Content-Type" : "application/strategic-merge-patch+json" ,
5746 },
47+ verify = SA_CA ,
5848 )
59- urllib . request . urlopen ( req , context = ctx )
49+ response . raise_for_status ( )
6050
6151
6252def main ():
63- if not [f for f in os .listdir (CA_DIR ) if not f .startswith ("." )]:
64- print ("CA directory empty, skipping" )
53+ ca_dir = os .environ ["CA_DIR" ]
54+ ca_file = os .path .join (ca_dir , os .environ ["CA_FILE_NAME" ])
55+ hash_file_path = os .path .join (ca_dir , HASH_FILE_NAME )
56+
57+ if not os .path .exists (ca_file ):
58+ print (f"CA file { ca_file } does not exist, skipping" )
6559 return
6660
67- current_hash = hash_dir ( CA_DIR )
61+ current_hash = hash_file ( ca_file )
6862
69- if not os .path .exists (HASH_FILE ):
70- with open (HASH_FILE , "w" ) as f :
63+ if not os .path .exists (hash_file_path ):
64+ with open (hash_file_path , "w" ) as f :
7165 f .write (current_hash )
7266 print ("Initial CA load, skipping restart" )
7367 return
7468
75- with open (HASH_FILE ) as f :
69+ with open (hash_file_path ) as f :
7670 previous_hash = f .read ().strip ()
7771
7872 if current_hash == previous_hash :
@@ -83,15 +77,15 @@ def main():
8377
8478 try :
8579 trigger_restart (namespace , deployment )
86- except urllib . error . URLError as e :
80+ except requests . RequestException as e :
8781 print (
8882 f"Failed to trigger restart for { deployment } : { e } " ,
8983 file = sys .stderr ,
9084 )
9185 sys .exit (1 )
9286
9387 # Persist hash only after successful restart
94- with open (HASH_FILE , "w" ) as f :
88+ with open (hash_file_path , "w" ) as f :
9589 f .write (current_hash )
9690 print (f"Rolling restart triggered for { deployment } " )
9791
0 commit comments