97424854cc069d92821c3307c7ada979c3a56b79
[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.delete(real_hrn)
134        else:
135            if not hrn in list:
136                list.append(hrn)
137
138    dict[listname] = list
139
140 def main():
141    process_options()
142
143    # if the user didn't tell us to do much of anything, then maybe he needs
144    # some help
145    if (not infile) and (not outfile) and (not dump):
146        showhelp()
147        return
148
149    if infile:
150        str = file(infile, "r").read()
151        record = GeniRecord(string = str)
152    else:
153        record = GeniRecord()
154
155    geni_info = record.get_geni_info()
156    geni_info_orig = geni_info.copy()
157
158    if email:
159        geni_info["email"] = email
160
161    if ip:
162        geni_info["ip"] = ip
163
164    if dns:
165        geni_info["dns"] = dns
166
167    if hrn:
168        record.name = hrn
169
170    if type:
171        record.type = type
172
173    if gidfile:
174        gid_str = file(gidfile, "r").read()
175        gid = GID(string=gid_str)
176        record.set_gid(gid)
177
178    if pubkeyfile:
179        if gidfile:
180            print "You should not use --gidfile and --pubkeyfile together"
181            sys.exit(-1)
182
183        if not record.name:
184            print "You must specify --hrn when you specify --pubkeyfile"
185            sys.exit(-1)
186
187        geni_info = record.get_geni_info()
188        geni_info["create_gid"] = True
189        geni_info["create_gid_hrn"] = record.name
190        geni_info["create_gid_key"] = load_publickey_string(pubkeyfile)
191
192    if researcher:
193        update_list(geni_info, "researcher", researcher)
194
195    if (geni_info != geni_info_orig):
196        record.set_geni_info(geni_info)
197
198    errorcheck(record)
199
200    if dump:
201        record.dump(False)
202
203    if outfile:
204        str = record.save_to_string()
205        file(outfile, "w").write(str)
206        print "wrote record to", outfile
207
208 if __name__=="__main__":
209    main()