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
12 from sfa.util.xrn import hrn_to_urn
15 WARNING : This script is not exactly thoroughly tested
19 * backup the /var/lib/sfa/authorities tree
20 * make sure to keep all this for a while
21 in case for example the old uuids turn out to be needed
25 Regenerates gids; mostly useful when your root gid is old or obsolete
26 for any other reason (like, it's still md5 signed)
30 all : regenerate everything no matter what, including toplevel gid
31 safe : regenerate everything *except* toplevel
32 incremental : was useful during development mostly;
36 authorities : a new gid is issued
37 users : a new gid is created with email, pubkey, and uuid restored from the previous ones
41 . do the backups - see above
42 . shutdown your sfa service
43 . rm -rf /var/lib/sfa/authorities
44 . run the script (run directly with python, no entry point is installed in PATH)
47 . on the client side, trash any old sscert or gids or similar
53 def __init__(self, session, tophrn):
54 self.session = session
57 def load_local_records(self):
59 read the database for records that start with tophrn.*
62 # just making sure we don't mess with anything else
63 # than our own local business
64 self.records = self.session.query(RegRecord)\
65 .filter(RegRecord.hrn.op('~')("{}.*".format(self.tophrn)))\
66 .order_by(RegRecord.hrn)
68 def regenerate(self, policy='safe'):
70 For all local records, gid gets regenerated
71 policy parameter works as follows
73 all gids get renewed, including toplevel hrn, no matter what
75 gid for toplevel hrn gets regenerated only if not yet existing
76 in SFA_DATA_DIR (i.e. /var/lib/sfa/authorities/<hrn>/hrn.{gid,key})
79 recreate only for entities not present in SFA_DATA_DIR
82 count_auths, count_users, count_slices = 0, 0, 0
83 hierarchy = Hierarchy()
84 for record in self.records:
86 ########## not an autority nor a user nor a slice: ignored
87 # Just wondering what other type it could be...
88 if record.type not in ['authority', 'user', 'slice']:
91 message = '[GID cleared]'
93 print("SKP (non-auth) {} {} : {}"
94 .format(message, record.type, record.hrn))
96 ########## toplevel : be careful
97 if record.hrn == self.tophrn:
99 print("SKP (toplevel) - type={} - policy={}"
100 .format(record.type, policy))
102 ########## user : rebuild a gid from pubkey and email
103 if record.type == 'user':
104 hrn = str(record.hrn)
105 urn = hrn_to_urn(hrn, str(record.type))
106 gid = record.get_gid_object()
107 uuid = gid.get_uuid()
108 pub = gid.get_pubkey()
109 email = gid.get_email()
110 print("pub {} uuid {}... email {}".format(pub, str(uuid)[:6], email))
111 new_gid = hierarchy.create_gid(urn, uuid, pub, email=email)
112 new_gid_str = new_gid.save_to_string()
113 record.gid = new_gid_str
114 print("NEW {} {} [{}]".format(record.type, record.hrn, email))
117 ########## authorities
118 if record.type == 'authority':
119 if policy in ('all', 'safe'):
122 redo = not hierarchy.auth_exists(record.hrn)
124 print("IGN (existing) {}".format(record.hrn))
126 print("NEW {} {}".format(record.type, record.hrn))
127 # because we have it sorted we should not need create_parents
128 gid = hierarchy.create_auth(str(record.hrn))
132 if record.type == 'slice':
133 hrn = str(record.hrn)
134 urn = hrn_to_urn(hrn, str(record.type))
135 gid = record.get_gid_object()
136 uuid = gid.get_uuid()
137 pub = gid.get_pubkey()
138 print("pub {} uuid {}...".format(pub, str(uuid)[:6]))
139 new_gid = hierarchy.create_gid(urn, uuid, pub)
140 new_gid_str = new_gid.save_to_string()
141 record.gid = new_gid_str
142 print("NEW {} {}".format(record.type, record.hrn))
146 print("Committing to the DB {} new auth gids and {} new user gids and {} new slice gids"
147 .format(count_auths, count_users, count_slices))
148 self.session.commit()
152 parser = ArgumentParser()
153 parser.add_argument("--policy", choices=('all', 'safe', 'incremental'),
155 args = parser.parse_args()
157 self.load_local_records()
158 return 0 if self.regenerate(args.policy) else 1
161 if __name__ == '__main__':
162 session = alchemy.session()
163 tophrn = Config().SFA_REGISTRY_ROOT_AUTH
164 SfaResetGids(session, tophrn).main()