td 0.10.36 → 0.10.37

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,3 +1,28 @@
1
+
2
+ == 2012-08-06 version 0.10.37
3
+
4
+ * Added access control
5
+ * acl:list
6
+ * acl:grant <subject> <action> <scope>
7
+ * acl:revoke <subject> <action> <scope>
8
+ * Added multiuser features
9
+ * org:list
10
+ * org:show <name>
11
+ * org:create <name>
12
+ * org:delete <name>
13
+ * user:list
14
+ * user:show <name>
15
+ * user:create <name>
16
+ * user:delete <name>
17
+ * user:apikey:list <name>
18
+ * role:list
19
+ * role:show <name>
20
+ * role:create <name>
21
+ * role:delete <name>
22
+ * role:grant <name> <user>
23
+ * role:revoke <name> <user>
24
+
25
+
1
26
  == 2012-07-27 version 0.10.36
2
27
 
3
28
  * More friendly message for 'td account'
@@ -0,0 +1,53 @@
1
+
2
+ module TreasureData
3
+ module Command
4
+
5
+ def acl_list(op)
6
+ op.cmd_parse
7
+
8
+ client = get_client
9
+
10
+ acl = client.access_controls
11
+
12
+ rows = []
13
+ acl.each {|ac|
14
+ rows << {:Subject => ac.subject, :Action => ac.action, :Scope => ac.scope, :"Grant option" => ac.grant_option}
15
+ }
16
+
17
+ puts cmd_render_table(rows, :fields => [:Subject, :Action, :Scope, :"Grant option"])
18
+
19
+ if rows.empty?
20
+ $stderr.puts "There are no access controls."
21
+ $stderr.puts "Use '#{$prog} acl:grant <subject> <action> <scope>' to grant permissions."
22
+ end
23
+ end
24
+
25
+ def acl_grant(op)
26
+ grant_option = true
27
+
28
+ op.on('--no-grant-option', '-N', 'Grant without grant option', TrueClass) {|b|
29
+ grant_option = !b
30
+ }
31
+
32
+ subject, action, scope = op.cmd_parse
33
+
34
+ client = get_client
35
+
36
+ client.grant_access_control(subject, action, scope, grant_option)
37
+
38
+ $stderr.puts "Access control [#{subject} #{action} #{scope}] is created #{grant_option? ? 'with' : 'without'} grant option."
39
+ end
40
+
41
+ def acl_revoke(op)
42
+ subject, action, scope = op.cmd_parse
43
+
44
+ client = get_client
45
+
46
+ client.revoke_access_control(subject, action, scope)
47
+
48
+ $stderr.puts "Access control [#{subject} #{action} #{scope}] is created."
49
+ end
50
+
51
+ # TODO acl_test
52
+ end
53
+ end
@@ -266,6 +266,29 @@ module List
266
266
  add_list 'apikey:show', %w[], 'Show Treasure Data API key'
267
267
  add_list 'apikey:set', %w[apikey], 'Set Treasure Data API key'
268
268
 
269
+ add_list 'user:list', %w[], 'Show list of users'
270
+ add_list 'user:show', %w[name], 'Show an user'
271
+ add_list 'user:create', %w[name], 'Create an user'
272
+ add_list 'user:delete', %w[name], 'Delete an user'
273
+ add_list 'user:apikey:list', %w[name], 'Show API keys'
274
+
275
+ add_list 'role:list', %w[], 'Show list of roles'
276
+ add_list 'role:show', %w[name], 'Show a role'
277
+ add_list 'role:create', %w[name], 'Create a role'
278
+ add_list 'role:delete', %w[name], 'Delete a role'
279
+ add_list 'role:grant', %w[name user], 'Grant role to an user'
280
+ add_list 'role:revoke', %w[name user], 'Revoke role from an user'
281
+
282
+ add_list 'org:list', %w[], 'Show list of organizations'
283
+ add_list 'org:show', %w[name], 'Show an organizations'
284
+ add_list 'org:create', %w[name], 'Create an organizations'
285
+ add_list 'org:delete', %w[name], 'Delete an organizations'
286
+
287
+ add_list 'acl:list', %w[], 'Show list of access controls'
288
+ add_list 'acl:grant', %w[subject action scope], 'Grant an access control'
289
+ add_list 'acl:revoke', %w[subject action scope], 'Revoke an access control'
290
+ # TODO acl:test
291
+
269
292
  add_list 'aggr:list', %w[], 'Show list of aggregation schemas'
270
293
  add_list 'aggr:show', %w[name], 'Describe a aggregation schema'
271
294
  add_list 'aggr:create', %w[name relation_key], 'Create a aggregation schema'
@@ -318,6 +341,23 @@ module List
318
341
  add_alias 'jobs', 'job:list'
319
342
  add_alias 'kill', 'job:kill'
320
343
 
344
+ add_alias 'user', 'user:show'
345
+ add_alias 'users', 'user:list'
346
+ add_alias 'user:apikey', 'user:apikey:list'
347
+ add_alias 'user:apikeys', 'user:apikey:list'
348
+
349
+ add_alias 'role', 'role:show'
350
+ add_alias 'roles', 'role:list'
351
+
352
+ add_alias 'org', 'org:show'
353
+ add_alias 'orgs', 'org:list'
354
+ add_alias 'organization', 'org:create'
355
+ add_alias 'organization', 'org:delete'
356
+ add_alias 'organization', 'org:list'
357
+
358
+ add_alias 'acl', 'acl:list'
359
+ add_alias 'acls', 'acl:list'
360
+
321
361
  add_alias 'aggr', 'aggr:show'
322
362
  add_alias 'aggrs', 'aggr:list'
323
363
 
@@ -0,0 +1,63 @@
1
+
2
+ module TreasureData
3
+ module Command
4
+
5
+ def org_show(op)
6
+ name = op.cmd_parse
7
+
8
+ client = get_client
9
+
10
+ orgs = client.organizations
11
+ org = orgs.find {|org| name == org.name }
12
+ unless org
13
+ $stderr.puts "Organization '#{name}' does not exist."
14
+ $stderr.puts "Use '#{$prog} org:create <name>' to create an organization."
15
+ exit 1
16
+ end
17
+
18
+ $stderr.puts "Name : #{org.name}"
19
+ end
20
+
21
+ def org_list(op)
22
+ op.cmd_parse
23
+
24
+ client = get_client
25
+
26
+ orgs = client.organizations
27
+
28
+ rows = []
29
+ orgs.each {|org|
30
+ rows << {:Name => org.name}
31
+ }
32
+
33
+ puts cmd_render_table(rows, :fields => [:Name])
34
+
35
+ if rows.empty?
36
+ $stderr.puts "There are no organizations."
37
+ $stderr.puts "Use '#{$prog} org:create <name>' to create an organization."
38
+ end
39
+ end
40
+
41
+ def org_create(op)
42
+ name = op.cmd_parse
43
+
44
+ client = get_client
45
+
46
+ client.create_organization(name)
47
+
48
+ $stderr.puts "Organization '#{name}' is created."
49
+ end
50
+
51
+ def org_delete(op)
52
+ name = op.cmd_parse
53
+
54
+ client = get_client
55
+
56
+ client.delete_organization(name)
57
+
58
+ $stderr.puts "Organization '#{name}' is deleted."
59
+ end
60
+
61
+ end
62
+ end
63
+
@@ -0,0 +1,91 @@
1
+
2
+ module TreasureData
3
+ module Command
4
+
5
+ def role_show(op)
6
+ name = op.cmd_parse
7
+
8
+ client = get_client
9
+
10
+ roles = client.roles
11
+ role = roles.find {|role| name == role.name }
12
+ unless role
13
+ $stderr.puts "Role '#{name}' does not exist."
14
+ $stderr.puts "Use '#{$prog} role:create <name>' to create a role."
15
+ exit 1
16
+ end
17
+
18
+ $stderr.puts "Name : #{role.name}"
19
+ $stderr.puts "Organization : #{role.org_name}"
20
+ $stderr.puts "Users : #{role.user_names.join(', ')}"
21
+ end
22
+
23
+ def role_list(op)
24
+ op.cmd_parse
25
+
26
+ client = get_client
27
+
28
+ roles = client.roles
29
+
30
+ rows = []
31
+ roles.each {|role|
32
+ rows << {:Name => role.name, :Organization => role.org_name, :Users => role.user_names.join(',')}
33
+ }
34
+
35
+ puts cmd_render_table(rows, :fields => [:Name, :Organization, :Users])
36
+
37
+ if rows.empty?
38
+ $stderr.puts "There are no roles."
39
+ $stderr.puts "Use '#{$prog} org:create <name>' to create a role."
40
+ end
41
+ end
42
+
43
+ def role_create(op)
44
+ org = nil
45
+
46
+ op.on('-g', '--org ORGANIZATION', "create the role under this organization") {|s|
47
+ org = s
48
+ }
49
+
50
+ name = op.cmd_parse
51
+
52
+ client = get_client
53
+
54
+ client.create_role(name, org)
55
+
56
+ $stderr.puts "Role '#{name}' is created."
57
+ end
58
+
59
+ def role_delete(op)
60
+ name = op.cmd_parse
61
+
62
+ client = get_client
63
+
64
+ client.delete_role(name)
65
+
66
+ $stderr.puts "Role '#{name}' is deleted."
67
+ end
68
+
69
+ def role_grant(op)
70
+ name, user = op.cmd_parse
71
+
72
+ client = get_client
73
+
74
+ client.grant_role(name, user)
75
+
76
+ $stderr.puts "Role '#{name}' is granted to user '#{user}'."
77
+ end
78
+
79
+ def role_revoke(op)
80
+ name, user = op.cmd_parse
81
+
82
+ client = get_client
83
+
84
+ client.revoke_role(name, user)
85
+
86
+ $stderr.puts "Role '#{name}' is revoked from user '#{user}'."
87
+ end
88
+
89
+ end
90
+ end
91
+
@@ -24,7 +24,7 @@ module Command
24
24
 
25
25
  s = client.schedules
26
26
  s.each {|sched|
27
- scheds << {:Name => sched.name, :Cron => sched.cron, :Result => sched.rset_name, :Query => sched.query}
27
+ scheds << {:Name => sched.name, :Cron => sched.cron, :Result => sched.result_url, :Query => sched.query}
28
28
  }
29
29
  scheds = scheds.sort_by {|map|
30
30
  map[:Name]
@@ -35,7 +35,7 @@ module Command
35
35
  j.each {|job|
36
36
  start = job.start_at
37
37
  elapsed = cmd_format_elapsed(start, job.end_at)
38
- jobs << {:JobID => job.job_id, :Status => job.status, :Query => job.query.to_s, :Start => (start ? start.localtime : ''), :Elapsed => elapsed, :Result => job.rset_name}
38
+ jobs << {:JobID => job.job_id, :Status => job.status, :Query => job.query.to_s, :Start => (start ? start.localtime : ''), :Elapsed => elapsed, :Result => job.result_url}
39
39
  }
40
40
  x2, y2 = status_render(0, 0, "[Jobs]", jobs, :fields => [:JobID, :Status, :Start, :Elapsed, :Result, :Query])
41
41
 
@@ -47,14 +47,14 @@ module Command
47
47
  }
48
48
  x3, y3 = status_render(0, 0, "[Tables]", tables, :fields => [:Database, :Table, :Count])
49
49
 
50
- r = client.result_sets
51
- r.each {|rset|
52
- results << {:Name => rset.name}
50
+ rs = client.results
51
+ rs.each {|r|
52
+ results << {:Name => r.name, :URL => r.url}
53
53
  }
54
54
  results = results.sort_by {|map|
55
55
  map[:Name]
56
56
  }
57
- x4, y4 = status_render(x3+2, y3, "[Results]", results, :fields => [:Name])
57
+ x4, y4 = status_render(x3+2, y3, "[Results]", results, :fields => [:Name, :URL])
58
58
 
59
59
  (y3-y4-1).times do
60
60
  print "\eD"
@@ -0,0 +1,187 @@
1
+
2
+ module TreasureData
3
+ module Command
4
+
5
+ def user_show(op)
6
+ name = op.cmd_parse
7
+
8
+ client = get_client
9
+
10
+ users = client.users
11
+ user = users.find {|user| name == user.name }
12
+ unless user
13
+ $stderr.puts "User '#{name}' does not exist."
14
+ $stderr.puts "Use '#{$prog} user:create <name>' to create an user."
15
+ exit 1
16
+ end
17
+
18
+ $stderr.puts "Name : #{user.name}"
19
+ $stderr.puts "Organization : #{user.org_name}"
20
+ $stderr.puts "Email : #{user.email}"
21
+ $stderr.puts "Roles : #{user.role_names.join(', ')}"
22
+ end
23
+
24
+ def user_list(op)
25
+ op.cmd_parse
26
+
27
+ client = get_client
28
+
29
+ users = client.users
30
+
31
+ rows = []
32
+ users.each {|user|
33
+ rows << {:Name => user.name, :Organization => user.org_name, :Email => user.email, :Roles => user.role_names.join(',')}
34
+ }
35
+
36
+ puts cmd_render_table(rows, :fields => [:Name, :Organization, :Email, :Roles])
37
+
38
+ if rows.empty?
39
+ $stderr.puts "There are no users."
40
+ $stderr.puts "Use '#{$prog} user:create <name>' to create an users."
41
+ end
42
+ end
43
+
44
+ def user_create(op)
45
+ org = nil
46
+ email = nil
47
+ random_password = false
48
+
49
+ op.on('-g', '--org ORGANIZATION', "create the user under this organization") {|s|
50
+ org = s
51
+ }
52
+
53
+ op.on('-e', '--email EMAIL', "Use this email address to identify the user") {|s|
54
+ email = s
55
+ }
56
+
57
+ op.on('-R', '--random-password', "Generate random password", TrueClass) {|b|
58
+ random_password = b
59
+ }
60
+
61
+ name = op.cmd_parse
62
+
63
+ unless email
64
+ $stderr.puts "-e, --email EMAIL option is required."
65
+ exit 1
66
+ end
67
+
68
+ if random_password
69
+ lower = ('a'..'z').to_a
70
+ upper = ('A'..'Z').to_a
71
+ digit = ('0'..'9').to_a
72
+ symbol = %w[_ @ - + ;]
73
+
74
+ r = []
75
+ 3.times { r << lower.sort_by{rand}.first }
76
+ 3.times { r << upper.sort_by{rand}.first }
77
+ 2.times { r << digit.sort_by{rand}.first }
78
+ 1.times { r << symbol.sort_by{rand}.first }
79
+ password = r.sort_by{rand}.join
80
+
81
+ puts "Password: #{password}"
82
+
83
+ else
84
+ 3.times do
85
+ begin
86
+ system "stty -echo" # TODO termios
87
+ print "Password (typing will be hidden): "
88
+ password = STDIN.gets || ""
89
+ password = password[0..-2] # strip \n
90
+ rescue Interrupt
91
+ $stderr.print "\ncanceled."
92
+ exit 1
93
+ ensure
94
+ system "stty echo" # TODO termios
95
+ print "\n"
96
+ end
97
+
98
+ if password.empty?
99
+ $stderr.puts "canceled."
100
+ exit 0
101
+ end
102
+
103
+ begin
104
+ system "stty -echo" # TODO termios
105
+ print "Retype password: "
106
+ password2 = STDIN.gets || ""
107
+ password2 = password2[0..-2] # strip \n
108
+ rescue Interrupt
109
+ $stderr.print "\ncanceled."
110
+ exit 1
111
+ ensure
112
+ system "stty echo" # TODO termios
113
+ print "\n"
114
+ end
115
+
116
+ if password == password2
117
+ break
118
+ end
119
+
120
+ puts "Doesn't match."
121
+ end
122
+ end
123
+
124
+ client = get_client(:ssl => true)
125
+
126
+ client.add_user(name, org)
127
+
128
+ ok = false
129
+ begin
130
+ client.change_email(name, email)
131
+ client.change_password(name, password)
132
+ client.add_apikey(name)
133
+ ok = true
134
+ ensure
135
+ unless ok
136
+ client.remove_user(name)
137
+ end
138
+ end
139
+
140
+ $stderr.puts "User '#{name}' is created."
141
+ $stderr.puts "Use '#{$prog} user:apikeys #{name}' to show the API key."
142
+ end
143
+
144
+ def user_delete(op)
145
+ name = op.cmd_parse
146
+
147
+ client = get_client
148
+
149
+ client.remove_user(name)
150
+
151
+ $stderr.puts "User '#{name}' is deleted."
152
+ end
153
+
154
+ ## TODO user:email:change <name> <email>
155
+ #def user_email_change(op)
156
+ #end
157
+
158
+ ## TODO user:apikey:add <name>
159
+ #def user_apikey_add(op)
160
+ #end
161
+
162
+ ## TODO user:apikey:remove <name> <apikey>
163
+ #def user_apikey_remove(op)
164
+ #end
165
+
166
+ def user_apikey_list(op)
167
+ name = op.cmd_parse
168
+
169
+ client = get_client
170
+
171
+ keys = client.list_apikeys(name)
172
+
173
+ rows = []
174
+ keys.each {|key|
175
+ rows << {:Key => key}
176
+ }
177
+
178
+ puts cmd_render_table(rows, :fields => [:Key])
179
+ end
180
+
181
+ ## TODO user:password:change <name>
182
+ #def user_password_change(op)
183
+ #end
184
+
185
+ end
186
+ end
187
+
data/lib/td/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module TreasureData
2
2
 
3
- VERSION = '0.10.36'
3
+ VERSION = '0.10.37'
4
4
 
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: td
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.36
4
+ version: 0.10.37
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-28 00:00:00.000000000 Z
12
+ date: 2012-08-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: msgpack
@@ -66,7 +66,7 @@ dependencies:
66
66
  requirements:
67
67
  - - ~>
68
68
  - !ruby/object:Gem::Version
69
- version: 0.8.20
69
+ version: 0.8.21
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -74,7 +74,7 @@ dependencies:
74
74
  requirements:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
- version: 0.8.20
77
+ version: 0.8.21
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: td-logger
80
80
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +136,7 @@ files:
136
136
  - data/sample_apache_gen.rb
137
137
  - lib/td.rb
138
138
  - lib/td/command/account.rb
139
+ - lib/td/command/acl.rb
139
140
  - lib/td/command/aggr.rb
140
141
  - lib/td/command/apikey.rb
141
142
  - lib/td/command/bulk_import.rb
@@ -146,8 +147,10 @@ files:
146
147
  - lib/td/command/import.rb
147
148
  - lib/td/command/job.rb
148
149
  - lib/td/command/list.rb
150
+ - lib/td/command/org.rb
149
151
  - lib/td/command/query.rb
150
152
  - lib/td/command/result.rb
153
+ - lib/td/command/role.rb
151
154
  - lib/td/command/runner.rb
152
155
  - lib/td/command/sample.rb
153
156
  - lib/td/command/sched.rb
@@ -155,6 +158,7 @@ files:
155
158
  - lib/td/command/server.rb
156
159
  - lib/td/command/status.rb
157
160
  - lib/td/command/table.rb
161
+ - lib/td/command/user.rb
158
162
  - lib/td/compat_core.rb
159
163
  - lib/td/compat_gzip_reader.rb
160
164
  - lib/td/config.rb
@@ -162,8 +166,7 @@ files:
162
166
  - lib/td/version.rb
163
167
  - ChangeLog
164
168
  - README.rdoc
165
- - !binary |-
166
- YmluL3Rk
169
+ - bin/td
167
170
  homepage: http://treasure-data.com/
168
171
  licenses: []
169
172
  post_install_message:
@@ -184,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
187
  version: '0'
185
188
  requirements: []
186
189
  rubyforge_project:
187
- rubygems_version: 1.8.21
190
+ rubygems_version: 1.8.23
188
191
  signing_key:
189
192
  specification_version: 3
190
193
  summary: CLI to manage data on Treasure Data, the Hadoop-based cloud data warehousing