fix bug when removing researchers
[sfa.git] / cmdline / editRecord.py
1 #! /usr/bin/env python
2 from __future__ import with_statement
3
4 # sfi -- slice-based facility interface
5
6 import sys
7 import os, os.path
8 import getopt
9 import tempfile
10 from geni.util.cert import Keypair, Certificate
11 from geni.util.credential import Credential
12 from geni.util.geniclient import GeniClient
13 from geni.util.record import GeniRecord
14 from geni.util.gid import GID
15 from geni.util.gid import create_uuid
16
17 pubkeyfile = None
18 infile = None
19 outfile = None
20 gidfile = None
21 email = None
22 ip = None
23 dns = None
24 hrn = None
25 type = None
26 dump = False
27 researcher = []
28
29 long_opts = ["infile=", "outfile=", "email=", "ip=", "dns=", "gidfile=", "hrn=", "pubkeyfile=", "type=", "addresearcher=", "delresearcher=", "dump"]
30
31 def showhelp():
32    print "syntax: editRecord.py <options>"
33    print "    --help                ... show help"
34    print "    --infile <name>       ... read record from file"
35    print "    --outfile <name>      ... write record to file"
36    print "    --dump                ... dump record to stdout"
37    print "    --gidfile <fn>        ... load gid from file"
38    print "    --pubkeyfile <name>   ... key to use when creating gid"
39    print "    --hrn <name>          ... set hrn"
40    print "    --type <type>         ... set type (user|slice|sa|ma|...)"
41    print "    --email <addr>        ... user: set email address"
42    print "    --ip <addr>           ... node: set ip address"
43    print "    --dns <hostname>      ... node: set hostname"
44    print "    --addresearcher <hrn> ... slice: add researcher"
45    print "    --delresearcher <hrn> ... slice: delete researcher"
46
47 def load_publickey_string(fn):
48    f = file(fn,"r")
49    key_string = f.read()
50
51    # if the filename is a private key file, then extract the public key
52    if "PRIVATE KEY" in key_string:
53        outfn = tempfile.mktemp()
54        cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
55        os.system(cmd)
56        f = file(outfn, "r")
57        key_string = f.read()
58        os.remove(outfn)
59
60    return key_string
61
62 def process_options():
63    global infile, outfile
64    global email, ip, dns, gidfile, hrn, type
65    global researcher
66    global dump
67    global pubkeyfile
68
69    (options, args) = getopt.getopt(sys.argv[1:], '', long_opts)
70    for opt in options:
71        name = opt[0]
72        val = opt[1]
73
74        if name == "--help":
75            showhelp()
76            sys.exit(0)
77        elif name == "--infile":
78            infile = val
79        elif name == "--outfile":
80            outfile = val
81        elif name == "--email":
82            email = val
83        elif name == "--ip":
84            ip = val
85        elif name == "--dns":
86            dns = val
87        elif name == "--gidfile":
88            gidfile = val
89        elif name == "--pubkeyfile":
90            pubkeyfile = val
91        elif name == "--hrn":
92            hrn = val
93        elif name == "--type":
94            type = val
95        elif name == "--dump":
96            dump = True
97        elif name == "--addresearcher":
98            researcher.append(val)
99        elif name == "--delresearcher":
100            researcher.append("-" + val)
101
102 def errorcheck(record):
103    geni_info = record.get_geni_info()
104
105    if not record.type:
106        print "Warning: no type specified"
107    if not record.type in ["user", "sa", "ma", "slice", "node"]:
108        print "Warning: unknown record type"
109    if not record.name:
110        print "Warning: unknown record name"
111    if (not record.gid) and (not ("create_gid" in geni_info)):
112        print "Warning: unknown record gid"
113        print "   use --hrn and --pubkeyfile to cause a gid to be created"
114
115    if record.type == "user":
116        if not geni_info.get("email",None):
117            print "Warning: unknown email in user record"
118
119    if record.type == "node":
120        if not geni_info.get("ip",None):
121            print "Warning: unknown ip in node record"
122        if not geni_info.get("dns",None):
123            print "Warning: unknown dns in node record"
124
125 # updates is a list of items to add or remove. If an item starts with "-", then
126 # it will be removed. Otherwise it will be added
127 def update_list(dict, listname, updates):
128    list = dict.get(listname, [])
129    for hrn in updates:
130        if hrn.startswith("-"):
131            real_hrn = hrn[1:]
132            if real_hrn in list:
133                list.remove(real_hrn)
134            else:
135                print "Error:", real_hrn, "is not in researcher list:", list 
136        else:
137            if not hrn in list:
138                list.append(hrn)
139
140    dict[listname] = list
141
142 def main():
143    process_options()
144
145    # if the user didn't tell us to do much of anything, then maybe he needs
146    # some help
147    if (not infile) and (not outfile) and (not dump):
148        showhelp()
149        return
150
151    if infile:
152        str = file(infile, "r").read()
153        record = GeniRecord(string = str)
154    else:
155        record = GeniRecord()
156
157    geni_info = record.get_geni_info()
158    geni_info_orig = geni_info.copy()
159
160    if email:
161        geni_info["email"] = email
162
163    if ip:
164        geni_info["ip"] = ip
165
166    if dns:
167        geni_info["dns"] = dns
168
169    if hrn:
170        record.name = hrn
171
172    if type:
173        record.type = type
174
175    if gidfile:
176        gid_str = file(gidfile, "r").read()
177        gid = GID(string=gid_str)
178        record.set_gid(gid)
179
180    if pubkeyfile:
181        if gidfile:
182            print "You should not use --gidfile and --pubkeyfile together"
183            sys.exit(-1)
184
185        if not record.name:
186            print "You must specify --hrn when you specify --pubkeyfile"
187            sys.exit(-1)
188
189        geni_info = record.get_geni_info()
190        geni_info["create_gid"] = True
191        geni_info["create_gid_hrn"] = record.name
192        geni_info["create_gid_key"] = load_publickey_string(pubkeyfile)
193
194    if researcher:
195        update_list(geni_info, "researcher", researcher)
196
197    if (geni_info != geni_info_orig):
198        record.set_geni_info(geni_info)
199
200    errorcheck(record)
201
202    if dump:
203        record.dump(False)
204
205    if outfile:
206        str = record.save_to_string()
207        file(outfile, "w").write(str)
208        print "wrote record to", outfile
209
210 if __name__=="__main__":
211    main()