This repository has been archived by the owner on Mar 6, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
cernbox-share
executable file
·245 lines (178 loc) · 9.24 KB
/
cernbox-share
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#!/usr/bin/env python2
# -*- python -*-
#
# The CERNBox Project.
#
# Author:
# License: AGPL
#
#$Id: $
#
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Perform internal setup of the environment.
# This is a Copy/Paste logic which must stay in THIS file
def standardSetup():
import sys, os.path
# insert the path to cernafs based on the relative position of this scrip inside the service directory tree
exeDir = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0])))
pythonDir = os.path.join(exeDir, 'python' )
sys.path.insert(0, pythonDir)
import cernbox_utils.setup
cernbox_utils.setup.standardSetup(sys.argv[0]) # execute a setup hook
standardSetup()
del standardSetup
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
config = None
logger = None
args = None
eos = None # EOS interface instance
db = None # DB interface instance
import cernbox_utils
def print_json(obj):
if args.json:
import json
print json.dumps(obj,ensure_ascii=False) # allows unicode characters from eos output
def print_json_error(msg):
print_json({"error" : str(msg)})
import os, os.path, sys
import subprocess
def main():
global config,logger
import cernbox_utils.script
from cernbox_utils.eos import is_special_folder
parser=cernbox_utils.script.arg_parser(description='Manipulate regular shares to users and egroups. ')
subparser = parser.add_subparsers(title='command',dest='cmd')
subcmd = subparser.add_parser('add', help="add a share to the system")
subcmd.add_argument("path", help="path on storage")
subcmd.add_argument("owner", help="share owner")
subcmd.add_argument("sharee", help="share with u:USER or egroup:GROUP") #TODO: OC_INTEGRATION add UNIX groups => g:<group>
subcmd.add_argument("acl", help="access rights: r (read), rw (read-write)")
subcmd = subparser.add_parser('remove', help="remove share from the system") #TODO: OC_INTEGRATION remove by share id
subcmd.add_argument("path", help="path on storage")
subcmd.add_argument("owner", help="share owner")
subcmd.add_argument("sharee", help="share with u:USER or egroup:GROUP")
subcmd = subparser.add_parser('list-shared-by', help="list all shares created by the user")
subcmd.add_argument("user", help="specify owner")
subcmd.add_argument('--include-broken', default=False, action='store_true', help="include deleted or broken shares in he output")
subcmd.add_argument("--flat-list", default=False, action='store_true', help="flat listing with raw DB values")
# TODO: OC_INTEGRATION add option to specify path
# TODO: OC_INTEGRATION --ocs instead of --flat-list
subcmd = subparser.add_parser('list-shared-with', help="list all shares given to the user")
subcmd.add_argument("user", help="specify sharee")
subcmd.add_argument('--include-broken', default=False, action='store_true', help="include deleted or broken shares in he output")
subcmd.add_argument("--flat-list", default=False, action='store_true', help="flat listing with raw DB values")
# TODO: OC_INTEGRATION add update command to update permissions by share id
# ADMIN COMMANDS
subcmd = subparser.add_parser('acl_update', help="update the sharing ACL for a path and all subdirectories")
subcmd.add_argument("pathspec", help="path or inode:n")
#subcmd.add_argument("owner", help="owner of the share")
subcmd = subparser.add_parser('summary', help="provide overview of shares per user or for all users")
subcmd.add_argument("shares_owner", help="'-' to check all users in the system")
subcmd.add_argument("--sort-by", default="all", action='store', help="sort output by the number of: 'all' shares, 'link' shares, 'regular' shares ")
subcmd = subparser.add_parser('verify', help="verify consistency of shares owned by the given user")
subcmd.add_argument("--fix", default=False, action='store_true', help="fix any sharing inconsistencies in the storage and in the database")
subcmd.add_argument("--fix-all-perms", default=False, action='store_true', help="fix all permisions (even if different and potentially overriding manualy set permissions)")
subcmd.add_argument("--deep-fs-check", default=False, action='store_true', help="check the entire filesystem of the share_owner to misconfigured ACLs also in non-shared folders")
subcmd.add_argument("--homedir", default="", action='store', help="override home directory if not set then it defaults to user home directory of shares_owner")
subcmd.add_argument("--project-name", default="", action='store', help="check project and override home directory")
subcmd.add_argument("--logdir",default="",action="store",help="log directory")
subcmd.add_argument("--orphans", default=False, action='store_true', help="check for shares already marked as orphans")
subcmd.add_argument("--public-links", default=False, action='store_true', help="Check public links as well (if not, it will only check internal shares)")
subcmd.add_argument("--with-files", default=False, action='store_true', help="Check single file shares besides folders")
subcmd.add_argument("shares_owner", help="'-' to check all users in the system")
subcmd = subparser.add_parser('remove-orphan-xbits', help="remove xbits which were set in the initial implementation in the parent ACLs")
subcmd.add_argument("--fix", default=False, action='store_true', help="fix it")
subcmd.add_argument("--logdir",default="",action="store",help="log directory")
subcmd.add_argument("path", help="top of the tree to check")
subcmd = subparser.add_parser('show-other-acls', help="show all directories which have an acl which does not contain name (useful to see which directories are open besides the owner)")
subcmd.add_argument("--ignore-special-directories", default=False, action='store_true', help="ignore special system directories (%s)"%is_special_folder.__doc__)
subcmd.add_argument("path", help="top of the tree to check")
subcmd.add_argument("name", help="name in ACL")
parser.set_defaults(configfile="/etc/cboxshareadmin.ini")
global args
args = parser.parse_args()
config = cernbox_utils.script.configure(args.configfile)
logger = cernbox_utils.script.getLogger(level=args.loglevel)
logger.info("Using DB: %s",config['dbhost'])
logger.info("Using EOS: %s",config['eos_mgm_url'])
global eos,db
import cernbox_utils.db, cernbox_utils.eos
db = cernbox_utils.db.ShareDB()
eos = cernbox_utils.eos.EOS(config['eos_mgm_url'])
eos.role=(0,0)
#unit_test_swanprj()
import cernbox_utils.sharing
if args.cmd == "acl_update":
import cernbox_utils.cmd_share_admin
cernbox_utils.cmd_share_admin.acl_update(args,config,eos,db)
if args.cmd == "remove":
try:
print_json(cmd_remove(args))
except CmdError:
sys.exit(2)
if args.cmd == "add":
try:
print_json(cmd_add(args))
except CmdError:
sys.exit(2)
if args.cmd == "list-shared-by":
try:
print_json(cmd_list_shares(args,'owner'))
except CmdError:
sys.exit(2)
if args.cmd == "list-shared-with":
try:
print_json(cmd_list_shares(args,'sharee'))
except CmdError:
sys.exit(2)
if args.cmd == "show-other-acls":
import cernbox_utils.cmd_share_admin
cernbox_utils.cmd_share_admin.show_other_acl(args,config,eos,db)
if args.cmd == "remove-orphan-xbits":
import cernbox_utils.cmd_share_admin
cernbox_utils.cmd_share_admin.remove_orphan_xbits(args,config,eos,db)
if args.cmd == "summary":
import cernbox_utils.cmd_share_admin
cernbox_utils.cmd_share_admin.summary(args,config,eos,db)
if args.cmd == "verify":
import cernbox_utils.cmd_share_admin
cernbox_utils.cmd_share_admin.verify(args,config,eos,db)
class CmdError(Exception):
pass
def cmd_remove(args):
from cernbox_utils.sharing import split_sharee
share_with_entity,share_with_who = split_sharee(args.sharee)
path = args.path #split_path(args.path)
f = check_share_target(path, args.owner)
shares=db.get_share(sharee=share_with_who,owner=args.owner,fid=f.ino)
if len(shares)>1:
msg="Multiple shares exist, share ids %s"%[s.id for s in shares]
logger.error(msg)
print_json_error(msg)
sys.exit(2)
if len(shares)==0:
msg="Share from user %s to %s does not exist at path %s"%(args.owner,share_with_who,f.file)
logger.error(msg)
print_json_error(msg)
sys.exit(2)
#print 'would delete',shares[0].id
db.delete_share(shares[0].id)
try:
# modify storage ACL
cernbox_utils.sharing.update_acls(f.ino,eos,db,args.owner)
except Exception,x:
logger.critical("Something went pretty wrong... %s %s",hash(x),x)
print_json_error("Critical error %s"%hash(x))
#rollback the insert?
raise
sys.exit(2)
def cmd_add(args):
import cernbox_utils.sharing
return cernbox_utils.sharing.add_share(args.owner,args.path,args.sharee,args.acl)
def cmd_list_shares(args,role):
import cernbox_utils.sharing
groups={}
retobj = cernbox_utils.sharing.list_shares(args.user,role,groups,None,"regular",args.flat_list,False,db,eos)
return {'shares':retobj}
if __name__ == "__main__":
sys.exit(main())