td 0.10.36 → 0.10.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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