jdc 0.2.1.pre → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. data/LICENSE +24 -1277
  2. data/README.md +102 -0
  3. data/bin/jdc +2 -12
  4. data/{lib/tunnel/helper-app → caldecott_helper}/server.rb +5 -5
  5. data/{lib/tunnel/config → config}/clients.yml +2 -2
  6. data/config/micro/paths.yml +22 -0
  7. data/config/micro/refresh_ip.rb +20 -0
  8. data/lib/cli/commands/admin.rb +58 -0
  9. data/lib/cli/commands/apps.rb +1129 -0
  10. data/lib/cli/commands/base.rb +228 -0
  11. data/lib/cli/commands/manifest.rb +56 -0
  12. data/lib/cli/commands/micro.rb +115 -0
  13. data/lib/cli/commands/misc.rb +126 -0
  14. data/lib/cli/commands/services.rb +178 -0
  15. data/lib/cli/commands/user.rb +14 -0
  16. data/lib/cli/config.rb +173 -0
  17. data/lib/cli/console_helper.rb +170 -0
  18. data/lib/cli/core_ext.rb +122 -0
  19. data/lib/cli/errors.rb +19 -0
  20. data/lib/cli/frameworks.rb +265 -0
  21. data/lib/cli/manifest_helper.rb +300 -0
  22. data/lib/cli/runner.rb +505 -0
  23. data/lib/cli/services_helper.rb +84 -0
  24. data/lib/cli/tunnel_helper.rb +332 -0
  25. data/lib/cli/usage.rb +86 -0
  26. data/lib/cli/version.rb +7 -0
  27. data/lib/cli/zip_util.rb +77 -0
  28. data/lib/cli.rb +53 -0
  29. data/lib/jdc/client.rb +457 -0
  30. data/lib/jdc/const.rb +25 -0
  31. data/lib/jdc/micro/switcher/base.rb +97 -0
  32. data/lib/{micro → jdc/micro}/switcher/darwin.rb +3 -5
  33. data/lib/{micro → jdc/micro}/switcher/dummy.rb +1 -1
  34. data/lib/jdc/micro/switcher/linux.rb +16 -0
  35. data/lib/{micro → jdc/micro}/switcher/windows.rb +5 -5
  36. data/lib/{micro → jdc/micro}/vmrun.rb +19 -26
  37. data/lib/{micro → jdc}/micro.rb +15 -15
  38. data/lib/jdc/signature/version.rb +27 -0
  39. data/lib/jdc/signer.rb +13 -0
  40. data/lib/jdc/timer.rb +12 -0
  41. data/lib/jdc.rb +2 -15
  42. metadata +210 -360
  43. data/Rakefile +0 -13
  44. data/lib/admin/README.md +0 -15
  45. data/lib/admin/curl.rb +0 -60
  46. data/lib/admin/guid.rb +0 -89
  47. data/lib/admin/plugin.rb +0 -6
  48. data/lib/admin/service_auth_token.rb +0 -94
  49. data/lib/admin/service_broker/add.rb +0 -47
  50. data/lib/admin/service_broker/service_brokers.rb +0 -24
  51. data/lib/admin/set_quota.rb +0 -44
  52. data/lib/console/README.md +0 -8
  53. data/lib/console/console.rb +0 -187
  54. data/lib/console/plugin.rb +0 -33
  55. data/lib/jdc/cli/app/app.rb +0 -43
  56. data/lib/jdc/cli/app/apps.rb +0 -87
  57. data/lib/jdc/cli/app/base.rb +0 -72
  58. data/lib/jdc/cli/app/delete.rb +0 -95
  59. data/lib/jdc/cli/app/deprecated.rb +0 -11
  60. data/lib/jdc/cli/app/env.rb +0 -78
  61. data/lib/jdc/cli/app/events.rb +0 -45
  62. data/lib/jdc/cli/app/files.rb +0 -137
  63. data/lib/jdc/cli/app/health.rb +0 -26
  64. data/lib/jdc/cli/app/instances.rb +0 -53
  65. data/lib/jdc/cli/app/logs.rb +0 -76
  66. data/lib/jdc/cli/app/push/create.rb +0 -108
  67. data/lib/jdc/cli/app/push/interactions.rb +0 -86
  68. data/lib/jdc/cli/app/push/sync.rb +0 -57
  69. data/lib/jdc/cli/app/push.rb +0 -103
  70. data/lib/jdc/cli/app/rename.rb +0 -35
  71. data/lib/jdc/cli/app/restart.rb +0 -31
  72. data/lib/jdc/cli/app/scale.rb +0 -63
  73. data/lib/jdc/cli/app/start.rb +0 -161
  74. data/lib/jdc/cli/app/stats.rb +0 -67
  75. data/lib/jdc/cli/app/stop.rb +0 -27
  76. data/lib/jdc/cli/domain/base.rb +0 -9
  77. data/lib/jdc/cli/domain/domains.rb +0 -40
  78. data/lib/jdc/cli/domain/map.rb +0 -55
  79. data/lib/jdc/cli/domain/unmap.rb +0 -56
  80. data/lib/jdc/cli/help.rb +0 -15
  81. data/lib/jdc/cli/interactive.rb +0 -105
  82. data/lib/jdc/cli/login_requirements.rb +0 -15
  83. data/lib/jdc/cli/organization/base.rb +0 -14
  84. data/lib/jdc/cli/organization/create.rb +0 -37
  85. data/lib/jdc/cli/organization/delete.rb +0 -63
  86. data/lib/jdc/cli/organization/org.rb +0 -45
  87. data/lib/jdc/cli/organization/orgs.rb +0 -30
  88. data/lib/jdc/cli/organization/rename.rb +0 -37
  89. data/lib/jdc/cli/populators/base.rb +0 -16
  90. data/lib/jdc/cli/populators/organization.rb +0 -32
  91. data/lib/jdc/cli/populators/populator_methods.rb +0 -64
  92. data/lib/jdc/cli/populators/space.rb +0 -33
  93. data/lib/jdc/cli/populators/target.rb +0 -13
  94. data/lib/jdc/cli/route/base.rb +0 -9
  95. data/lib/jdc/cli/route/delete.rb +0 -28
  96. data/lib/jdc/cli/route/map.rb +0 -68
  97. data/lib/jdc/cli/route/routes.rb +0 -26
  98. data/lib/jdc/cli/route/unmap.rb +0 -56
  99. data/lib/jdc/cli/service/base.rb +0 -9
  100. data/lib/jdc/cli/service/bind.rb +0 -44
  101. data/lib/jdc/cli/service/create.rb +0 -159
  102. data/lib/jdc/cli/service/delete.rb +0 -83
  103. data/lib/jdc/cli/service/rename.rb +0 -36
  104. data/lib/jdc/cli/service/service.rb +0 -42
  105. data/lib/jdc/cli/service/service_instance_helper.rb +0 -99
  106. data/lib/jdc/cli/service/services.rb +0 -111
  107. data/lib/jdc/cli/service/unbind.rb +0 -37
  108. data/lib/jdc/cli/space/base.rb +0 -29
  109. data/lib/jdc/cli/space/create.rb +0 -67
  110. data/lib/jdc/cli/space/delete.rb +0 -56
  111. data/lib/jdc/cli/space/rename.rb +0 -38
  112. data/lib/jdc/cli/space/space.rb +0 -66
  113. data/lib/jdc/cli/space/spaces.rb +0 -57
  114. data/lib/jdc/cli/space/switch.rb +0 -19
  115. data/lib/jdc/cli/start/base.rb +0 -41
  116. data/lib/jdc/cli/start/colors.rb +0 -13
  117. data/lib/jdc/cli/start/target.rb +0 -50
  118. data/lib/jdc/cli/start/target_prettifier.rb +0 -17
  119. data/lib/jdc/cli/start/targets.rb +0 -16
  120. data/lib/jdc/cli/user/base.rb +0 -30
  121. data/lib/jdc/cli/user/create.rb +0 -52
  122. data/lib/jdc/cli/user/passwd.rb +0 -37
  123. data/lib/jdc/cli/user/register.rb +0 -43
  124. data/lib/jdc/cli/user/users.rb +0 -32
  125. data/lib/jdc/cli.rb +0 -556
  126. data/lib/jdc/constants.rb +0 -11
  127. data/lib/jdc/errors.rb +0 -19
  128. data/lib/jdc/object_extensions.rb +0 -15
  129. data/lib/jdc/plugin.rb +0 -56
  130. data/lib/jdc/spacing.rb +0 -89
  131. data/lib/jdc/spec_helper.rb +0 -1
  132. data/lib/jdc/test_support.rb +0 -6
  133. data/lib/jdc/version.rb +0 -3
  134. data/lib/manifests/errors.rb +0 -35
  135. data/lib/manifests/loader/builder.rb +0 -39
  136. data/lib/manifests/loader/normalizer.rb +0 -145
  137. data/lib/manifests/loader/resolver.rb +0 -79
  138. data/lib/manifests/loader.rb +0 -31
  139. data/lib/manifests/manifests.rb +0 -344
  140. data/lib/manifests/plugin.rb +0 -140
  141. data/lib/micro/README.md +0 -9
  142. data/lib/micro/errors.rb +0 -4
  143. data/lib/micro/plugin.rb +0 -197
  144. data/lib/micro/switcher/base.rb +0 -79
  145. data/lib/micro/switcher/linux.rb +0 -16
  146. data/lib/tasks/gem_release.rake +0 -42
  147. data/lib/tunnel/README.md +0 -29
  148. data/lib/tunnel/helper-app/Gemfile +0 -10
  149. data/lib/tunnel/helper-app/Gemfile.lock +0 -48
  150. data/lib/tunnel/plugin.rb +0 -183
  151. data/lib/tunnel/tunnel.rb +0 -295
@@ -0,0 +1,228 @@
1
+ require 'rubygems'
2
+ require 'interact'
3
+ require 'terminal-table/import'
4
+
5
+ module JDC::Cli
6
+
7
+ module Command
8
+
9
+ class Base
10
+ include Interactive
11
+
12
+ attr_reader :no_prompt, :prompt_ok
13
+
14
+ MANIFEST = "manifest.yml"
15
+
16
+ def initialize(options={})
17
+ @options = options.dup
18
+ @no_prompt = @options[:noprompts]
19
+ @prompt_ok = !no_prompt
20
+
21
+ # Suppress colorize on Windows systems for now.
22
+ if WINDOWS
23
+ JDC::Cli::Config.colorize = false
24
+ end
25
+
26
+ @path = @options[:path] || '.'
27
+
28
+ load_manifest manifest_file if manifest_file
29
+ end
30
+
31
+ def manifest_file
32
+ return @options[:manifest] if @options[:manifest]
33
+ return @manifest_file if @manifest_file
34
+
35
+ where = File.expand_path(@path)
36
+ while true
37
+ if File.exists?(File.join(where, MANIFEST))
38
+ @manifest_file = File.join(where, MANIFEST)
39
+ break
40
+ elsif File.basename(where) == "/"
41
+ @manifest_file = nil
42
+ break
43
+ else
44
+ where = File.expand_path("../", where)
45
+ end
46
+ end
47
+
48
+ @manifest_file
49
+ end
50
+
51
+ def load_manifest_structure(file)
52
+ manifest = YAML.load_file file
53
+
54
+ Array(manifest["inherit"]).each do |p|
55
+ manifest = merge_parent(manifest, p)
56
+ end
57
+
58
+ if apps = manifest["applications"]
59
+ apps.each do |k, v|
60
+ abs = File.expand_path(k, file)
61
+ if Dir.pwd.start_with? abs
62
+ manifest = merge_manifest(manifest, v)
63
+ end
64
+ end
65
+ end
66
+
67
+ manifest
68
+ end
69
+
70
+ def resolve_manifest(manifest)
71
+ if apps = manifest["applications"]
72
+ apps.each_value do |v|
73
+ resolve_lexically(v, [manifest])
74
+ end
75
+ end
76
+
77
+ resolve_lexically(manifest, [manifest])
78
+ end
79
+
80
+ def load_manifest(file)
81
+ @manifest = load_manifest_structure(file)
82
+ resolve_manifest(@manifest)
83
+ end
84
+
85
+ def merge_parent(child, path)
86
+ file = File.expand_path("../" + path, manifest_file)
87
+ merge_manifest(child, load_manifest_structure(file))
88
+ end
89
+
90
+ def merge_manifest(child, parent)
91
+ merge = proc do |_, old, new|
92
+ if new.is_a?(Hash) and old.is_a?(Hash)
93
+ old.merge(new, &merge)
94
+ else
95
+ new
96
+ end
97
+ end
98
+
99
+ parent.merge(child, &merge)
100
+ end
101
+
102
+ def resolve_lexically(val, ctx = [@manifest])
103
+ case val
104
+ when Hash
105
+ val.each_value do |v|
106
+ resolve_lexically(v, [val] + ctx)
107
+ end
108
+ when Array
109
+ val.each do |v|
110
+ resolve_lexically(v, ctx)
111
+ end
112
+ when String
113
+ val.gsub!(/\$\{([[:alnum:]\-]+)\}/) do
114
+ resolve_symbol($1, ctx)
115
+ end
116
+ end
117
+
118
+ nil
119
+ end
120
+
121
+ def resolve_symbol(sym, ctx)
122
+ case sym
123
+ when "target-base"
124
+ target_base(ctx)
125
+
126
+ when "target-url"
127
+ target_url(ctx)
128
+
129
+ when "random-word"
130
+ "%04x" % [rand(0x0100000)]
131
+
132
+ else
133
+ found = find_symbol(sym, ctx)
134
+
135
+ if found
136
+ resolve_lexically(found, ctx)
137
+ found
138
+ else
139
+ err(sym, "Unknown symbol in manifest: ")
140
+ end
141
+ end
142
+ end
143
+
144
+ def find_symbol(sym, ctx)
145
+ ctx.each do |h|
146
+ if val = resolve_in(h, sym)
147
+ return val
148
+ end
149
+ end
150
+
151
+ nil
152
+ end
153
+
154
+ def resolve_in(hash, *where)
155
+ find_in_hash(hash, ["properties"] + where) ||
156
+ find_in_hash(hash, ["applications", @application] + where) ||
157
+ find_in_hash(hash, where)
158
+ end
159
+
160
+ def manifest(*where)
161
+ resolve_in(@manifest, *where)
162
+ end
163
+
164
+ def find_in_hash(hash, where)
165
+ what = hash
166
+ where.each do |x|
167
+ return nil unless what.is_a?(Hash)
168
+ what = what[x]
169
+ end
170
+
171
+ what
172
+ end
173
+
174
+ def target_url(ctx = [])
175
+ find_symbol("target", ctx) ||
176
+ (@client && @client.target) ||
177
+ JDC::Cli::Config.target_url
178
+ end
179
+
180
+ def target_base(ctx = [])
181
+ JDC::Cli::Config.base_of(find_symbol("target", ctx) || target_url)
182
+ end
183
+
184
+ # Inject a client to help in testing.
185
+ def client(cli=nil)
186
+ @client ||= cli
187
+ return @client if @client
188
+ @client = JDC::Client.new(target_url)
189
+ @client.trace = JDC::Cli::Config.trace if JDC::Cli::Config.trace
190
+ @client.proxy_for @options[:proxy] if @options[:proxy]
191
+ @client
192
+ end
193
+
194
+ def client_info
195
+ @client_info ||= client.info
196
+ end
197
+
198
+ #need to delete
199
+ def auth_token
200
+ @auth_token = JDC::Cli::Config.auth_token(@options[:token_file])
201
+ end
202
+
203
+ def runtimes_info
204
+ return @runtimes if @runtimes
205
+ info = client_info
206
+ @runtimes = {}
207
+ if info[:frameworks]
208
+ info[:frameworks].each_value do |f|
209
+ next unless f[:runtimes]
210
+ f[:runtimes].each { |r| @runtimes[r[:name]] = r}
211
+ end
212
+ end
213
+ @runtimes
214
+ end
215
+
216
+ def frameworks_info
217
+ return @frameworks if @frameworks
218
+ info = client_info
219
+ @frameworks = []
220
+ if info[:frameworks]
221
+ info[:frameworks].each_value { |f| @frameworks << [f[:name]] }
222
+ end
223
+ @frameworks
224
+ end
225
+ end
226
+ end
227
+ end
228
+
@@ -0,0 +1,56 @@
1
+ module JDC::Cli::Command
2
+ class Manifest < Base
3
+ include JDC::Cli::ManifestHelper
4
+
5
+ def initialize(options)
6
+ super
7
+
8
+ # don't resolve any of the manifest template stuff
9
+ if manifest_file
10
+ @manifest = load_manifest_structure manifest_file
11
+ else
12
+ @manifest = {}
13
+ end
14
+ end
15
+
16
+ def edit
17
+ build_manifest
18
+ save_manifest
19
+ end
20
+
21
+ def extend(which)
22
+ parent = load_manifest_structure which
23
+ @manifest = load_manifest_structure which
24
+
25
+ build_manifest
26
+
27
+ simplify(@manifest, parent)
28
+
29
+ @manifest["inherit"] ||= []
30
+ @manifest["inherit"] << which
31
+
32
+ save_manifest(ask("Save where?"))
33
+ end
34
+
35
+ private
36
+
37
+ def simplify(child, parent)
38
+ return unless child.is_a?(Hash) and parent.is_a?(Hash)
39
+
40
+ child.reject! do |k, v|
41
+ if v == parent[k]
42
+ puts "rejecting #{k}"
43
+ true
44
+ else
45
+ simplify(v, parent[k])
46
+ false
47
+ end
48
+ end
49
+ end
50
+
51
+ def build_manifest
52
+ @application = ask("Configure for which application?", :default => ".")
53
+ interact true
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,115 @@
1
+ module JDC::Cli::Command
2
+ class Micro < Base
3
+
4
+ def initialize(args)
5
+ super(args)
6
+ end
7
+
8
+ def offline(mode)
9
+ command('offline')
10
+ end
11
+
12
+ def online(mode)
13
+ command('online')
14
+ end
15
+
16
+ def status(mode)
17
+ command('status')
18
+ end
19
+
20
+ def command(cmd)
21
+ config = build_config
22
+ switcher(config).send(cmd)
23
+ store_config(config)
24
+ end
25
+
26
+ def switcher(config)
27
+ case Micro.platform
28
+ when :darwin
29
+ switcher = JDC::Micro::Switcher::Darwin.new(config)
30
+ when :linux
31
+ switcher = JDC::Micro::Switcher::Linux.new(config)
32
+ when :windows
33
+ switcher = JDC::Micro::Switcher::Windows.new(config)
34
+ when :dummy # for testing only
35
+ switcher = JDC::Micro::Switcher::Dummy.new(config)
36
+ else
37
+ err "unsupported platform: #{Micro.platform}"
38
+ end
39
+ end
40
+
41
+ # Returns the configuration needed to run the micro related subcommands.
42
+ # First loads saved config from file (if there is any), then overrides
43
+ # loaded values with command line arguments, and finally tries to guess
44
+ # in case neither was used:
45
+ # vmx location of micro.vmx file
46
+ # vmrun location of vmrun command
47
+ # password password for vcap user (in the guest vm)
48
+ # platform current platform
49
+ def build_config
50
+ conf = JDC::Cli::Config.micro # returns {} if there isn't a saved config
51
+
52
+ override(conf, 'vmx', true) do
53
+ locate_vmx(Micro.platform)
54
+ end
55
+
56
+ override(conf, 'vmrun', true) do
57
+ JDC::Micro::VMrun.locate(Micro.platform)
58
+ end
59
+
60
+ override(conf, 'password') do
61
+ @password = ask("Please enter your JingDong Cloud VM password (vcap user) password", :echo => "*")
62
+ end
63
+
64
+ conf['platform'] = Micro.platform
65
+
66
+ conf
67
+ end
68
+
69
+ # Save the cleartext password if --save is supplied.
70
+ # Note: it is due to vix we have to use a cleartext password :(
71
+ # Only if --password is used and not --save is the password deleted from the
72
+ # config file before it is stored to disk.
73
+ def store_config(config)
74
+ if @options[:save]
75
+ warn("cleartext password saved in: #{JDC::Cli::Config::MICRO_FILE}")
76
+ elsif @options[:password] || @password
77
+ config.delete('password')
78
+ end
79
+
80
+ JDC::Cli::Config.store_micro(config)
81
+ end
82
+
83
+ # override with command line arguments and yield the block in case the option isn't set
84
+ def override(config, option, escape=false, &blk)
85
+ # override if given on the command line
86
+ if opt = @options[option.to_sym]
87
+ opt = JDC::Micro.escape_path(opt) if escape
88
+ config[option] = opt
89
+ end
90
+ config[option] = yield unless config[option]
91
+ end
92
+
93
+ def locate_vmx(platform)
94
+ paths = YAML.load_file(JDC::Micro.config_file('paths.yml'))
95
+ vmx_paths = paths[platform.to_s]['vmx']
96
+ vmx = JDC::Micro.locate_file('micro.vmx', 'micro', vmx_paths)
97
+ err "Unable to locate micro.vmx, please supply --vmx option" unless vmx
98
+ vmx
99
+ end
100
+
101
+ def self.platform
102
+ case RUBY_PLATFORM
103
+ when /darwin/ # x86_64-darwin11.2.0
104
+ :darwin
105
+ when /linux/ # x86_64-linux
106
+ :linux
107
+ when /mingw|mswin32|cygwin/ # i386-mingw32
108
+ :windows
109
+ else
110
+ RUBY_PLATFORM
111
+ end
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,126 @@
1
+ module JDC::Cli::Command
2
+
3
+ class Misc < Base
4
+ def version
5
+ say "jdc #{JDC::Cli::VERSION}"
6
+ end
7
+
8
+ def target
9
+ return display JSON.pretty_generate({:target => target_url}) if @options[:json]
10
+ banner "[#{target_url}]"
11
+ end
12
+
13
+ def targets
14
+ targets = JDC::Cli::Config.targets
15
+ return display JSON.pretty_generate(targets) if @options[:json]
16
+ return display 'None specified' if targets.empty?
17
+ targets_table = table do |t|
18
+ t.headings = 'Target', 'Authorization'
19
+ targets.each { |target, token| t << [target, token] }
20
+ end
21
+ display "\n"
22
+ display targets_table
23
+ end
24
+
25
+ alias :tokens :targets
26
+
27
+ def set_target(target_url)
28
+ target_url = "http://#{target_url}" unless /^https?/ =~ target_url
29
+ target_url = target_url.gsub(/\/+$/, '')
30
+ client = JDC::Client.new(target_url)
31
+ unless client.target_valid?
32
+ if prompt_ok
33
+ display "Host is not available or is not valid: '#{target_url}'".red
34
+ show_response = ask "Would you like see the response?",
35
+ :default => false
36
+ display "\n<<<\n#{client.raw_info}\n>>>\n" if show_response
37
+ end
38
+ exit(false)
39
+ else
40
+ JDC::Cli::Config.store_target(target_url)
41
+ say "Successfully targeted to [#{target_url}]".green
42
+ end
43
+ end
44
+
45
+ def info
46
+ info = client_info
47
+ return display JSON.pretty_generate(info) if @options[:json]
48
+
49
+ display "\n#{info[:description]}"
50
+ display ""
51
+ display "Target: #{target_url} (v#{info[:version]})"
52
+ display "Client: v#{JDC::Cli::VERSION}"
53
+ if info[:user]
54
+ display ''
55
+ display "User: #{info[:user]}"
56
+ end
57
+ if usage = info[:usage] and limits = info[:limits]
58
+ tmem = pretty_size(limits[:memory]*1024*1024)
59
+ mem = pretty_size(usage[:memory]*1024*1024)
60
+ tser = limits[:services]
61
+ ser = usage[:services]
62
+ tapps = limits[:apps] || 0
63
+ apps = usage[:apps] || 0
64
+ display "Usage: Memory (#{mem} of #{tmem} total)"
65
+ display " Services (#{ser} of #{tser} total)"
66
+ display " Apps (#{apps} of #{tapps} total)" if limits[:apps]
67
+ end
68
+ end
69
+
70
+ def runtimes
71
+ return display JSON.pretty_generate(runtimes_info) if @options[:json]
72
+ return display "No Runtimes" if runtimes_info.empty?
73
+ rtable = table do |t|
74
+ t.headings = 'Name', 'Description', 'Version'
75
+ runtimes_info.each_value { |rt| t << [rt[:name], rt[:description], rt[:version]] }
76
+ end
77
+ display "\n"
78
+ display rtable
79
+ end
80
+
81
+ def frameworks
82
+ return display JSON.pretty_generate(frameworks_info) if @options[:json]
83
+ return display "No Frameworks" if frameworks_info.empty?
84
+ rtable = table do |t|
85
+ t.headings = ['Name']
86
+ frameworks_info.each { |f| t << f }
87
+ end
88
+ display "\n"
89
+ display rtable
90
+ end
91
+
92
+ def aliases
93
+ aliases = JDC::Cli::Config.aliases
94
+ return display JSON.pretty_generate(aliases) if @options[:json]
95
+ return display "No Aliases" if aliases.empty?
96
+ atable = table do |t|
97
+ t.headings = 'Alias', 'Command'
98
+ aliases.each { |k,v| t << [k, v] }
99
+ end
100
+ display "\n"
101
+ display atable
102
+ end
103
+
104
+ def alias(k, v=nil)
105
+ k,v = k.split('=') unless v
106
+ aliases = JDC::Cli::Config.aliases
107
+ aliases[k] = v
108
+ JDC::Cli::Config.store_aliases(aliases)
109
+ display "Successfully aliased '#{k}' to '#{v}'".green
110
+ end
111
+
112
+ def unalias(key)
113
+ aliases = JDC::Cli::Config.aliases
114
+ if aliases.has_key?(key)
115
+ aliases.delete(key)
116
+ JDC::Cli::Config.store_aliases(aliases)
117
+ display "Successfully unaliased '#{key}'".green
118
+ else
119
+ display "Unknown alias '#{key}'".red
120
+ end
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+
@@ -0,0 +1,178 @@
1
+ require "uuidtools"
2
+
3
+ module JDC::Cli::Command
4
+
5
+ class Services < Base
6
+ include JDC::Cli::ServicesHelper
7
+ include JDC::Cli::TunnelHelper
8
+
9
+ def services
10
+ ss = client.services_info
11
+ ps = client.services
12
+ ps.sort! {|a, b| a[:name] <=> b[:name] }
13
+
14
+ if @options[:json]
15
+ services = { :system => ss, :provisioned => ps }
16
+ return display JSON.pretty_generate(services)
17
+ end
18
+ display_system_services(ss)
19
+ display_provisioned_services(ps)
20
+ end
21
+
22
+ def create_service(service=nil, name=nil, appname=nil)
23
+ unless no_prompt || service
24
+ services = client.services_info
25
+ err 'No services available to provision' if services.empty?
26
+ service = ask(
27
+ "Which service would you like to provision?",
28
+ { :indexed => true,
29
+ :choices =>
30
+ services.values.collect { |type|
31
+ type.keys.collect(&:to_s)
32
+ }.flatten
33
+ }
34
+ )
35
+ end
36
+ name = @options[:name] unless name
37
+ unless name
38
+ name = random_service_name(service)
39
+ picked_name = true
40
+ end
41
+ create_service_banner(service, name, picked_name)
42
+ appname = @options[:bind] unless appname
43
+ bind_service_banner(name, appname) if appname
44
+ end
45
+
46
+ def delete_service(service=nil)
47
+ unless no_prompt || service
48
+ user_services = client.services
49
+ err 'No services available to delete' if user_services.empty?
50
+ service = ask(
51
+ "Which service would you like to delete?",
52
+ { :indexed => true,
53
+ :choices => user_services.collect { |s| s[:name] }
54
+ }
55
+ )
56
+ end
57
+ err "Service name required." unless service
58
+ display "Deleting service [#{service}]: ", false
59
+ client.delete_service(service)
60
+ display 'OK'.green
61
+ end
62
+
63
+ def bind_service(service, appname)
64
+ bind_service_banner(service, appname)
65
+ end
66
+
67
+ def unbind_service(service, appname)
68
+ unbind_service_banner(service, appname)
69
+ end
70
+
71
+ def clone_services(src_app, dest_app)
72
+ begin
73
+ src = client.app_info(src_app)
74
+ dest = client.app_info(dest_app)
75
+ rescue
76
+ end
77
+
78
+ err "Application '#{src_app}' does not exist" unless src
79
+ err "Application '#{dest_app}' does not exist" unless dest
80
+
81
+ services = src[:services]
82
+ err 'No services to clone' unless services && !services.empty?
83
+ services.each { |service| bind_service_banner(service, dest_app, false) }
84
+ check_app_for_restart(dest_app)
85
+ end
86
+
87
+ def tunnel(service=nil, client_name=nil)
88
+ unless defined? Caldecott
89
+ display "To use `jdc tunnel', you must first install Caldecott:"
90
+ display ""
91
+ display "\tgem install caldecott"
92
+ display ""
93
+ display "Note that you'll need a C compiler. If you're on OS X, Xcode"
94
+ display "will provide one. If you're on Windows, try DevKit."
95
+ display ""
96
+ display "This manual step will be removed in the future."
97
+ display ""
98
+ err "Caldecott is not installed."
99
+ end
100
+
101
+ ps = client.services
102
+ err "No services available to tunnel to" if ps.empty?
103
+
104
+ unless service
105
+ choices = ps.collect { |s| s[:name] }.sort
106
+ service = ask(
107
+ "Which service to tunnel to?",
108
+ :choices => choices,
109
+ :indexed => true
110
+ )
111
+ end
112
+
113
+ info = ps.select { |s| s[:name] == service }.first
114
+
115
+ err "Unknown service '#{service}'" unless info
116
+
117
+ port = pick_tunnel_port(@options[:port] || 10000)
118
+
119
+ if not tunnel_pushed?
120
+ display "Deploying tunnel application '#{tunnel_appname}'."
121
+ auth = UUIDTools::UUID.random_create.to_s
122
+ push_caldecott(auth)
123
+ bind_service_banner(service, tunnel_appname, false)
124
+ start_caldecott
125
+ else
126
+ auth = tunnel_auth
127
+ end
128
+
129
+ if not tunnel_healthy?(auth)
130
+ display "Redeploying tunnel application '#{tunnel_appname}'."
131
+
132
+ # We don't expect caldecott not to be running, so take the
133
+ # most aggressive restart method.. delete/re-push
134
+ client.delete_app(tunnel_appname)
135
+ invalidate_tunnel_app_info
136
+
137
+ push_caldecott(auth)
138
+ bind_service_banner(service, tunnel_appname, false)
139
+ start_caldecott
140
+ end
141
+
142
+ if not tunnel_bound?(service)
143
+ bind_service_banner(service, tunnel_appname)
144
+ end
145
+
146
+ conn_info = tunnel_connection_info info[:vendor], service, auth
147
+ display_tunnel_connection_info(conn_info)
148
+ display "Starting tunnel to #{service.bold} on port #{port.to_s.bold}."
149
+ start_tunnel(port, conn_info, auth)
150
+
151
+ clients = get_clients_for(info[:vendor])
152
+
153
+ if clients.empty?
154
+ client_name ||= "none"
155
+ else
156
+ client_name ||= ask(
157
+ "Which client would you like to start?",
158
+ :choices => ["none"] + clients.keys,
159
+ :indexed => true
160
+ )
161
+ end
162
+
163
+ if client_name == "none"
164
+ wait_for_tunnel_end
165
+ else
166
+ wait_for_tunnel_start(port)
167
+ unless start_local_prog(clients, client_name, conn_info, port)
168
+ err "'#{client_name}' execution failed; is it in your $PATH?"
169
+ end
170
+ end
171
+ end
172
+
173
+ def get_clients_for(type)
174
+ conf = JDC::Cli::Config.clients
175
+ conf[type] || {}
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,14 @@
1
+ module JDC::Cli::Command
2
+
3
+ class User < Base
4
+
5
+ def info
6
+ info = client_info
7
+ username = info[:user] || 'N/A'
8
+ return display JSON.pretty_generate([username]) if @options[:json]
9
+ display "\n[#{username}]"
10
+ end
11
+
12
+ end
13
+
14
+ end