as 0.3.18.11

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of as might be problematic. Click here for more details.

Files changed (44) hide show
  1. data/LICENSE +24 -0
  2. data/README.md +105 -0
  3. data/Rakefile +101 -0
  4. data/bin/as +6 -0
  5. data/caldecott_helper/Gemfile +10 -0
  6. data/caldecott_helper/Gemfile.lock +48 -0
  7. data/caldecott_helper/server.rb +43 -0
  8. data/config/clients.yml +17 -0
  9. data/config/micro/offline.conf +2 -0
  10. data/config/micro/paths.yml +22 -0
  11. data/config/micro/refresh_ip.rb +20 -0
  12. data/lib/cli/commands/admin.rb +80 -0
  13. data/lib/cli/commands/apps.rb +1208 -0
  14. data/lib/cli/commands/base.rb +233 -0
  15. data/lib/cli/commands/manifest.rb +56 -0
  16. data/lib/cli/commands/micro.rb +115 -0
  17. data/lib/cli/commands/misc.rb +140 -0
  18. data/lib/cli/commands/services.rb +217 -0
  19. data/lib/cli/commands/user.rb +65 -0
  20. data/lib/cli/config.rb +170 -0
  21. data/lib/cli/console_helper.rb +163 -0
  22. data/lib/cli/core_ext.rb +122 -0
  23. data/lib/cli/errors.rb +19 -0
  24. data/lib/cli/file_helper.rb +123 -0
  25. data/lib/cli/frameworks.rb +265 -0
  26. data/lib/cli/manifest_helper.rb +316 -0
  27. data/lib/cli/runner.rb +568 -0
  28. data/lib/cli/services_helper.rb +104 -0
  29. data/lib/cli/tunnel_helper.rb +336 -0
  30. data/lib/cli/usage.rb +125 -0
  31. data/lib/cli/version.rb +7 -0
  32. data/lib/cli/zip_util.rb +77 -0
  33. data/lib/cli.rb +48 -0
  34. data/lib/vmc/client.rb +558 -0
  35. data/lib/vmc/const.rb +27 -0
  36. data/lib/vmc/micro/switcher/base.rb +97 -0
  37. data/lib/vmc/micro/switcher/darwin.rb +19 -0
  38. data/lib/vmc/micro/switcher/dummy.rb +15 -0
  39. data/lib/vmc/micro/switcher/linux.rb +16 -0
  40. data/lib/vmc/micro/switcher/windows.rb +31 -0
  41. data/lib/vmc/micro/vmrun.rb +158 -0
  42. data/lib/vmc/micro.rb +56 -0
  43. data/lib/vmc.rb +3 -0
  44. metadata +270 -0
@@ -0,0 +1,233 @@
1
+ require 'rubygems'
2
+ require 'interact'
3
+ require 'terminal-table/import'
4
+
5
+ module VMC::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
+ VMC::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
+ client.infra = v['infra'] if v['infra']
61
+ abs = File.expand_path(k, file)
62
+ if Dir.pwd.start_with? abs
63
+ manifest = merge_manifest(manifest, v)
64
+ end
65
+ end
66
+ end
67
+
68
+ manifest
69
+ end
70
+
71
+ def resolve_manifest(manifest)
72
+ if apps = manifest["applications"]
73
+ apps.each_value do |v|
74
+ resolve_lexically(v, [manifest])
75
+ end
76
+ end
77
+
78
+ resolve_lexically(manifest, [manifest])
79
+ end
80
+
81
+ def load_manifest(file)
82
+ @manifest = load_manifest_structure(file)
83
+ resolve_manifest(@manifest)
84
+ end
85
+
86
+ def merge_parent(child, path)
87
+ file = File.expand_path("../" + path, manifest_file)
88
+ merge_manifest(child, load_manifest_structure(file))
89
+ end
90
+
91
+ def merge_manifest(child, parent)
92
+ merge = proc do |_, old, new|
93
+ if new.is_a?(Hash) and old.is_a?(Hash)
94
+ old.merge(new, &merge)
95
+ else
96
+ new
97
+ end
98
+ end
99
+
100
+ parent.merge(child, &merge)
101
+ end
102
+
103
+ def resolve_lexically(val, ctx = [@manifest])
104
+ case val
105
+ when Hash
106
+ val.each_value do |v|
107
+ resolve_lexically(v, [val] + ctx)
108
+ end
109
+ when Array
110
+ val.each do |v|
111
+ resolve_lexically(v, ctx)
112
+ end
113
+ when String
114
+ val.gsub!(/\$\{([[:alnum:]\-]+)\}/) do
115
+ resolve_symbol($1, ctx)
116
+ end
117
+ end
118
+
119
+ nil
120
+ end
121
+
122
+ def resolve_symbol(sym, ctx)
123
+ case sym
124
+ when "target-base"
125
+ target_base(ctx)
126
+
127
+ when "target-url"
128
+ target_url(ctx)
129
+
130
+ when "random-word"
131
+ "%04x" % [rand(0x0100000)]
132
+
133
+ else
134
+ found = find_symbol(sym, ctx)
135
+
136
+ if found
137
+ resolve_lexically(found, ctx)
138
+ found
139
+ else
140
+ err(sym, "Unknown symbol in manifest: ")
141
+ end
142
+ end
143
+ end
144
+
145
+ def find_symbol(sym, ctx)
146
+ ctx.each do |h|
147
+ if val = resolve_in(h, sym)
148
+ return val
149
+ end
150
+ end
151
+
152
+ nil
153
+ end
154
+
155
+ def resolve_in(hash, *where)
156
+ find_in_hash(hash, ["properties"] + where) ||
157
+ find_in_hash(hash, ["applications", @application] + where) ||
158
+ find_in_hash(hash, where)
159
+ end
160
+
161
+ def manifest(*where)
162
+ resolve_in(@manifest, *where)
163
+ end
164
+
165
+ def find_in_hash(hash, where)
166
+ what = hash
167
+ where.each do |x|
168
+ return nil unless what.is_a?(Hash)
169
+ what = what[x]
170
+ end
171
+
172
+ what
173
+ end
174
+
175
+ def target_url(ctx = [])
176
+ find_symbol("target", ctx) ||
177
+ (@client && @client.target) ||
178
+ VMC::Cli::Config.target_url
179
+ end
180
+
181
+ def target_base(ctx = [])
182
+ VMC::Cli::Config.base_of(find_symbol("target", ctx) || "api.#{client.suggest_url}")
183
+ end
184
+
185
+ # Inject a client to help in testing.
186
+ def client(cli=nil)
187
+ @client ||= cli
188
+ return @client if @client
189
+ @client = VMC::Client.new(target_url, auth_token)
190
+ @client.trace = VMC::Cli::Config.trace if VMC::Cli::Config.trace
191
+ @client.proxy_for @options[:proxy] if @options[:proxy]
192
+ @client
193
+ end
194
+
195
+ def client_info
196
+ @client_info ||= client.info
197
+ end
198
+
199
+ def auth_token
200
+ @auth_token = VMC::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
+
226
+ def default_infra
227
+ "aws"
228
+ end
229
+
230
+ end
231
+ end
232
+ end
233
+
@@ -0,0 +1,56 @@
1
+ module VMC::Cli::Command
2
+ class Manifest < Base
3
+ include VMC::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 VMC::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 = VMC::Micro::Switcher::Darwin.new(config)
30
+ when :linux
31
+ switcher = VMC::Micro::Switcher::Linux.new(config)
32
+ when :windows
33
+ switcher = VMC::Micro::Switcher::Windows.new(config)
34
+ when :dummy # for testing only
35
+ switcher = VMC::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 = VMC::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
+ VMC::Micro::VMrun.locate(Micro.platform)
58
+ end
59
+
60
+ override(conf, 'password') do
61
+ @password = ask("Please enter your Micro Cloud Foundry 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: #{VMC::Cli::Config::MICRO_FILE}")
76
+ elsif @options[:password] || @password
77
+ config.delete('password')
78
+ end
79
+
80
+ VMC::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 = VMC::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(VMC::Micro.config_file('paths.yml'))
95
+ vmx_paths = paths[platform.to_s]['vmx']
96
+ vmx = VMC::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,140 @@
1
+ module VMC::Cli::Command
2
+
3
+ class Misc < Base
4
+ def version
5
+ say "as #{VMC::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 = VMC::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 = "https://#{target_url}" unless /^https?/ =~ target_url
29
+ target_url = target_url.gsub(/\/+$/, '')
30
+ client = VMC::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
+ VMC::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 "For support visit #{info[:support]}"
51
+ display ""
52
+ display "Target: #{target_url} (v#{info[:version]})"
53
+ display "Client: v#{VMC::Cli::VERSION}"
54
+ if info[:user]
55
+ display ''
56
+ display "User: #{info[:user]}"
57
+ end
58
+ if usage = info[:usage] and limits = info[:limits]
59
+ tmem = pretty_size(limits[:memory]*1024*1024)
60
+ mem = pretty_size(usage[:memory]*1024*1024)
61
+ tser = limits[:services]
62
+ ser = usage[:services]
63
+ tapps = limits[:apps] || 0
64
+ apps = usage[:apps] || 0
65
+ display "Usage: Memory (#{mem} of #{tmem} total)"
66
+ display " Services (#{ser} of #{tser} total)"
67
+ display " Apps (#{apps} of #{tapps} total)" if limits[:apps]
68
+ end
69
+ end
70
+
71
+ def runtimes
72
+ raise VMC::Client::AuthError unless client.logged_in?
73
+ return display JSON.pretty_generate(runtimes_info) if @options[:json]
74
+ return display "No Runtimes" if runtimes_info.empty?
75
+ rtable = table do |t|
76
+ t.headings = 'Name', 'Description', 'Version'
77
+ runtimes_info.each_value { |rt| t << [rt[:name], rt[:description], rt[:version]] }
78
+ end
79
+ display "\n"
80
+ display rtable
81
+ end
82
+
83
+ def infras
84
+ infras_info = client.infras
85
+ return display "Multiple infras not supported" if infras_info.empty?
86
+ itable = table do |t|
87
+ t.headings = [ 'Name','Description' ]
88
+ infras_info.each { |i| t << [i[:infra], i[:description]] }
89
+ end
90
+ display "\n"
91
+ display itable
92
+ end
93
+
94
+ def frameworks
95
+ raise VMC::Client::AuthError unless client.logged_in?
96
+ return display JSON.pretty_generate(frameworks_info) if @options[:json]
97
+ return display "No Frameworks" if frameworks_info.empty?
98
+ rtable = table do |t|
99
+ t.headings = ['Name']
100
+ frameworks_info.each { |f| t << f }
101
+ end
102
+ display "\n"
103
+ display rtable
104
+ end
105
+
106
+ def aliases
107
+ aliases = VMC::Cli::Config.aliases
108
+ return display JSON.pretty_generate(aliases) if @options[:json]
109
+ return display "No Aliases" if aliases.empty?
110
+ atable = table do |t|
111
+ t.headings = 'Alias', 'Command'
112
+ aliases.each { |k,v| t << [k, v] }
113
+ end
114
+ display "\n"
115
+ display atable
116
+ end
117
+
118
+ def alias(k, v=nil)
119
+ k,v = k.split('=') unless v
120
+ aliases = VMC::Cli::Config.aliases
121
+ aliases[k] = v
122
+ VMC::Cli::Config.store_aliases(aliases)
123
+ display "Successfully aliased '#{k}' to '#{v}'".green
124
+ end
125
+
126
+ def unalias(key)
127
+ aliases = VMC::Cli::Config.aliases
128
+ if aliases.has_key?(key)
129
+ aliases.delete(key)
130
+ VMC::Cli::Config.store_aliases(aliases)
131
+ display "Successfully unaliased '#{key}'".green
132
+ else
133
+ display "Unknown alias '#{key}'".red
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+ end
140
+