3 from __future__ import print_function
5 from argparse import ArgumentParser
7 from sfa.util.config import Config
8 from sfa.storage.alchemy import alchemy
9 from sfa.storage.model import RegRecord
10 from sfa.trust.hierarchy import Hierarchy
11 from sfa.trust.certificate import convert_public_key, Keypair
14 WARNING : This script is not exactly thoroughly tested
18 * backup the /var/lib/sfa/authorities tree
19 * make sure to keep all this for a while
20 in case for example the old uuids turn out to be needed
24 Regenerates gids; mostly useful when your root gid is old or obsolete
25 for any other reason (like, it's still md5 signed)
29 all : regenerate everything no matter what, including toplevel gid
30 safe : regenerate everything *except* toplevel
31 incremental : was useful during development mostly;
35 authorities : a new gid is issued
36 users : a new gid is created with email, pubkey, and uuid restored from the previous ones
40 . do the backups - see above
41 . shutdown your sfa service
42 . rm -rf /var/lib/sfa/authorities
43 . run the script (run directly with python, no entry point is installed in PATH)
46 . on the client side, trash any old sscert or gids or similar
52 def __init__(self, session, tophrn):
53 self.session = session
56 def load_local_records(self):
58 read the database for records that start with tophrn.*
61 # just making sure we don't mess with anything else
62 # than our own local business
63 self.records = self.session.query(RegRecord)\
64 .filter(RegRecord.hrn.op('~')("{}.*".format(self.tophrn)))\
65 .order_by(RegRecord.hrn)
67 def regenerate(self, policy='safe'):
69 For all local records, gid gets regenerated
70 policy parameter works as follows
72 all gids get renewed, including toplevel hrn, no matter what
74 gid for toplevel hrn gets regenerated only if not yet existing
75 in SFA_DATA_DIR (i.e. /var/lib/sfa/authorities/<hrn>/hrn.{gid,key})
78 recreate only for entities not present in SFA_DATA_DIR
81 count_auths, count_users, count_slices = 0, 0, 0
82 hierarchy = Hierarchy()
83 for record in self.records:
85 ########## not an autority nor a user nor a slice: ignored
86 # Just wondering what other type it could be...
87 if record.type not in ['authority', 'user', 'slice']:
90 message = '[GID cleared]'
92 print("SKP (non-auth) {} {} : {}"
93 .format(message, record.type, record.hrn))
95 ########## toplevel : be careful
96 if record.hrn == self.tophrn:
98 print("SKP (toplevel) - type={} - policy={}"
99 .format(record.type, policy))
101 ########## user : rebuild a gid from pubkey and email
102 if record.type == 'user':
103 hrn = str(record.hrn)
104 gid = record.get_gid_object()
105 uuid = gid.get_uuid()
106 pub = gid.get_pubkey()
107 email = gid.get_email()
108 print("pub {} uuid {}... email {}".format(pub, str(uuid)[:6], email))
109 new_gid = hierarchy.create_gid(hrn, uuid, pub, email=email)
110 new_gid_str = new_gid.save_to_string()
111 record.gid = new_gid_str
112 print("NEW {} {} [{}]".format(record.type, record.hrn, email))
115 ########## authorities
116 if record.type == 'authority':
117 if policy in ('all', 'safe'):
120 redo = not hierarchy.auth_exists(record.hrn)
122 print("IGN (existing) {}".format(record.hrn))
124 print("NEW {} {}".format(record.type, record.hrn))
125 # because we have it sorted we should not need create_parents
126 gid = hierarchy.create_auth(str(record.hrn))
130 if record.type == 'slice':
131 hrn = str(record.hrn)
132 gid = record.get_gid_object()
133 uuid = gid.get_uuid()
134 pub = gid.get_pubkey()
135 print("pub {} uuid {}...".format(pub, str(uuid)[:6]))
136 new_gid = hierarchy.create_gid(hrn, uuid, pub)
137 new_gid_str = new_gid.save_to_string()
138 record.gid = new_gid_str
139 print("NEW {} {}".format(record.type, record.hrn))
143 print("Committing to the DB {} new auth gids and {} new user gids and {} new slice gids"
144 .format(count_auths, count_users, count_slices))
145 self.session.commit()
149 parser = ArgumentParser()
150 parser.add_argument("--policy", choices=('all', 'safe', 'incremental'),
152 args = parser.parse_args()
154 self.load_local_records()
155 return 0 if self.regenerate(args.policy) else 1
158 if __name__ == '__main__':
159 session = alchemy.session()
160 tophrn = Config().SFA_REGISTRY_ROOT_AUTH
162 SfaResetGids(session, tophrn).main()