appfog-vmc-plugin 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +47 -0
- data/lib/appfog-vmc-plugin/cfoundry.rb +4 -0
- data/lib/appfog-vmc-plugin/cfoundry/upload_helpers.rb +52 -0
- data/lib/appfog-vmc-plugin/cfoundry/v1/app.rb +25 -0
- data/lib/appfog-vmc-plugin/cfoundry/v1/base.rb +23 -0
- data/lib/appfog-vmc-plugin/cfoundry/v1/client.rb +84 -0
- data/lib/appfog-vmc-plugin/cfoundry/v1/infra.rb +28 -0
- data/lib/appfog-vmc-plugin/cfoundry/v1/service.rb +36 -0
- data/lib/appfog-vmc-plugin/cfoundry/v1/service_instance.rb +17 -0
- data/lib/appfog-vmc-plugin/commands/bind-all.rb +46 -0
- data/lib/appfog-vmc-plugin/commands/clone.rb +132 -0
- data/lib/appfog-vmc-plugin/commands/download.rb +24 -0
- data/lib/appfog-vmc-plugin/commands/export.rb +34 -0
- data/lib/appfog-vmc-plugin/commands/frameworks.rb +21 -0
- data/lib/appfog-vmc-plugin/commands/import.rb +32 -0
- data/lib/appfog-vmc-plugin/commands/infra.rb +36 -0
- data/lib/appfog-vmc-plugin/commands/pull.rb +25 -0
- data/lib/appfog-vmc-plugin/commands/runtimes.rb +21 -0
- data/lib/appfog-vmc-plugin/help.rb +18 -0
- data/lib/appfog-vmc-plugin/net_http.rb +11 -0
- data/lib/appfog-vmc-plugin/non_uaa.rb +47 -0
- data/lib/appfog-vmc-plugin/plugin.rb +16 -0
- data/lib/appfog-vmc-plugin/version.rb +3 -0
- data/lib/appfog-vmc-plugin/vmc.rb +4 -0
- data/lib/appfog-vmc-plugin/vmc/app/apps.rb +5 -0
- metadata +86 -0
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require "rake"
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
4
|
+
require "appfog-vmc-plugin/version"
|
5
|
+
|
6
|
+
task :default => :spec
|
7
|
+
|
8
|
+
desc "Run specs"
|
9
|
+
task :spec => ["bundler:install", "test:spec"]
|
10
|
+
|
11
|
+
desc "Run integration tests"
|
12
|
+
task :test => ["bundler:install", "test:integration"]
|
13
|
+
|
14
|
+
task :build do
|
15
|
+
sh "gem build appfog-vmc-plugin.gemspec"
|
16
|
+
end
|
17
|
+
|
18
|
+
task :install => :build do
|
19
|
+
sh "gem install --local appfog-vmc-plugin-#{AFCLIClone::VERSION}.gem"
|
20
|
+
end
|
21
|
+
|
22
|
+
task :uninstall do
|
23
|
+
sh "gem uninstall appfog-vmc-plugin"
|
24
|
+
end
|
25
|
+
|
26
|
+
task :reinstall => [:uninstall, :install]
|
27
|
+
|
28
|
+
task :release => :build do
|
29
|
+
sh "gem push appfog-vmc-plugin-#{AFCLIClone::VERSION}.gem"
|
30
|
+
end
|
31
|
+
|
32
|
+
namespace "bundler" do
|
33
|
+
desc "Install gems"
|
34
|
+
task "install" do
|
35
|
+
sh("bundle install")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
namespace "test" do
|
40
|
+
task "spec" do |t|
|
41
|
+
# nothing
|
42
|
+
end
|
43
|
+
|
44
|
+
task "integration" do |t|
|
45
|
+
sh("cd spec && bundle exec rake spec")
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Patched to support .afignore
|
2
|
+
module CFoundry
|
3
|
+
module UploadHelpers
|
4
|
+
def prepare_package(path, to)
|
5
|
+
if path =~ /\.(jar|war|zip)$/
|
6
|
+
CFoundry::Zip.unpack(path, to)
|
7
|
+
elsif war_file = Dir.glob("#{path}/*.war").first
|
8
|
+
CFoundry::Zip.unpack(war_file, to)
|
9
|
+
else
|
10
|
+
check_unreachable_links(path)
|
11
|
+
|
12
|
+
FileUtils.mkdir(to)
|
13
|
+
|
14
|
+
files = Dir.glob("#{path}/{*,.[^\.]*}")
|
15
|
+
|
16
|
+
exclude = UPLOAD_EXCLUDE
|
17
|
+
if File.exists?("#{path}/.vmcignore")
|
18
|
+
exclude += File.read("#{path}/.vmcignore").split(/\n+/)
|
19
|
+
end
|
20
|
+
|
21
|
+
# adds additional .afignore
|
22
|
+
if File.exists?("#{path}/.afignore")
|
23
|
+
exclude += File.read("#{path}/.afignore").split(/\n+/)
|
24
|
+
end
|
25
|
+
|
26
|
+
# prevent initial copying if we can, remove sub-files later
|
27
|
+
files.reject! do |f|
|
28
|
+
exclude.any? do |e|
|
29
|
+
File.fnmatch(f.sub(path + "/", ""), e)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
FileUtils.cp_r(files, to)
|
34
|
+
|
35
|
+
find_sockets(to).each do |s|
|
36
|
+
File.delete s
|
37
|
+
end
|
38
|
+
|
39
|
+
# remove ignored globs more thoroughly
|
40
|
+
#
|
41
|
+
# note that the above file list only includes toplevel
|
42
|
+
# files/directories for cp_r, so this is where sub-files/etc. are
|
43
|
+
# removed
|
44
|
+
exclude.each do |e|
|
45
|
+
Dir.glob("#{to}/#{e}").each do |f|
|
46
|
+
FileUtils.rm_rf(f)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Patched to support infra
|
2
|
+
module CFoundry::V1
|
3
|
+
class App
|
4
|
+
attribute :infra, :string, :at => [:infra, :provider], :default => 'aws'
|
5
|
+
|
6
|
+
alias_method :infra_name, :infra
|
7
|
+
alias_method :infra_name=, :infra=
|
8
|
+
|
9
|
+
def infra
|
10
|
+
@client.infra(infra_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def infra=(obj)
|
14
|
+
set_named(:infra, obj)
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
"\#<#{self.class.name} '#@guid'>"
|
19
|
+
end
|
20
|
+
|
21
|
+
# remap payload locations
|
22
|
+
write_locations[:framework] = [:staging, :framework]
|
23
|
+
write_locations[:runtime] = [:staging, :runtime]
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Patched to support legacy api proxy
|
2
|
+
module CFoundry::V1
|
3
|
+
class Base
|
4
|
+
def upload_app(name, zipfile, resources = [])
|
5
|
+
payload = {
|
6
|
+
:_method => "put",
|
7
|
+
:application =>
|
8
|
+
UploadIO.new(
|
9
|
+
if zipfile.is_a? File
|
10
|
+
zipfile
|
11
|
+
elsif zipfile.is_a? String
|
12
|
+
File.new(zipfile, "rb")
|
13
|
+
end,
|
14
|
+
"application/zip"),
|
15
|
+
:resources => MultiJson.dump(resources)
|
16
|
+
}
|
17
|
+
# Accept type overrided for compatibility with old api proxy, should just be '*/*'
|
18
|
+
post("apps", name, "application", :payload => payload, :multipart => true, :accept => '*/*; q=0.5, application/xml')
|
19
|
+
rescue EOFError
|
20
|
+
retry
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module CFoundry::V1
|
2
|
+
class Client
|
3
|
+
attr_reader :base
|
4
|
+
|
5
|
+
# Retrieve available infras.
|
6
|
+
def info_infras
|
7
|
+
@base.get("info", "infras", :accept => :json)
|
8
|
+
end
|
9
|
+
|
10
|
+
def infras(options = {})
|
11
|
+
@ins = info_infras unless @ins # cache infras
|
12
|
+
return unless @ins
|
13
|
+
|
14
|
+
infras = []
|
15
|
+
@ins.each do |inf|
|
16
|
+
infras <<
|
17
|
+
Infra.new(inf[:infra], inf[:name], inf[:description], inf[:base], inf[:locality], inf[:vendor])
|
18
|
+
end
|
19
|
+
|
20
|
+
infras
|
21
|
+
end
|
22
|
+
|
23
|
+
def infra(name)
|
24
|
+
infra_by_name(name) || Infra.new(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def infra_by_name(name)
|
28
|
+
infras.find { |i| i.name == name }
|
29
|
+
end
|
30
|
+
|
31
|
+
# Added to support downloads
|
32
|
+
def app_download(name, path)
|
33
|
+
body = @base.get("apps", name, "application")
|
34
|
+
file = File.new(path, "wb")
|
35
|
+
file.write(body)
|
36
|
+
file.close
|
37
|
+
end
|
38
|
+
|
39
|
+
# Added to support app pulls
|
40
|
+
def app_pull(name, dir)
|
41
|
+
body = @base.get("apps", name, "application")
|
42
|
+
file = Tempfile.new(name)
|
43
|
+
file.binmode
|
44
|
+
file.write(body)
|
45
|
+
file.close
|
46
|
+
CFoundry::Zip.unpack(file.path, dir)
|
47
|
+
file.unlink
|
48
|
+
end
|
49
|
+
|
50
|
+
# Retrieve available services.
|
51
|
+
def services(options = {})
|
52
|
+
services = []
|
53
|
+
|
54
|
+
@base.system_services.each do |infra, infra_services|
|
55
|
+
infra_services.each do |type, vendors|
|
56
|
+
vendors.each do |vendor, providers|
|
57
|
+
providers.each do |provider, properties|
|
58
|
+
properties.each do |_, meta|
|
59
|
+
meta[:supported_versions].each do |ver|
|
60
|
+
state = meta[:version_aliases].find { |k, v| v == ver }
|
61
|
+
|
62
|
+
services <<
|
63
|
+
Service.new(vendor.to_s, infra, ver.to_s, meta[:description],
|
64
|
+
type.to_s, provider.to_s, state && state.first,
|
65
|
+
meta[:plans], meta[:default_plan])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
services
|
74
|
+
end
|
75
|
+
|
76
|
+
def export_service(service_name)
|
77
|
+
@base.get("services", "export", service_name, :accept => :json)
|
78
|
+
end
|
79
|
+
|
80
|
+
def import_service(service_name, uri)
|
81
|
+
@base.post("services", "import", service_name, :payload => {:uri => uri}, :multipart => true, :accept => '*/*; q=0.5, application/xml')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CFoundry::V1
|
2
|
+
class Infra
|
3
|
+
attr_accessor :name
|
4
|
+
attr_accessor :infra
|
5
|
+
attr_accessor :description
|
6
|
+
attr_accessor :base
|
7
|
+
attr_accessor :locality
|
8
|
+
attr_accessor :vendor
|
9
|
+
|
10
|
+
def initialize(name, infra = nil, description = nil, base = nil, locality = nil, vendor = nil)
|
11
|
+
@name = name
|
12
|
+
@infra = infra
|
13
|
+
@description = description
|
14
|
+
@locality = locality
|
15
|
+
@vendor = vendor
|
16
|
+
@base = base
|
17
|
+
end
|
18
|
+
|
19
|
+
def eql?(other)
|
20
|
+
other.is_a?(self.class) && other.name == @nameidp
|
21
|
+
end
|
22
|
+
alias :== :eql?
|
23
|
+
|
24
|
+
def apps
|
25
|
+
[] # not supported by v1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module CFoundry::V1
|
2
|
+
class Service
|
3
|
+
attr_accessor :label, :infra, :version, :description, :type, :provider, :state, :plans, :default_plan
|
4
|
+
|
5
|
+
def initialize(label, infra, version = nil, description = nil,
|
6
|
+
type = nil, provider = "core", state = nil,
|
7
|
+
plans = [], default_plan = nil)
|
8
|
+
@label = label
|
9
|
+
@infra = infra
|
10
|
+
@description = description
|
11
|
+
@version = version
|
12
|
+
@type = type
|
13
|
+
@provider = provider
|
14
|
+
@state = state
|
15
|
+
@plans = plans
|
16
|
+
@default_plan = default_plan
|
17
|
+
end
|
18
|
+
|
19
|
+
def eql?(other)
|
20
|
+
other.is_a?(self.class) && other.label == @label
|
21
|
+
end
|
22
|
+
alias :== :eql?
|
23
|
+
|
24
|
+
def active
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def deprecated?
|
29
|
+
@state == :deprecated
|
30
|
+
end
|
31
|
+
|
32
|
+
def current?
|
33
|
+
@state == :current
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Patched to support infra
|
2
|
+
module CFoundry::V1
|
3
|
+
class ServiceInstance
|
4
|
+
attribute :infra, :string, :at => [:infra, :provider], :default => 'aws'
|
5
|
+
|
6
|
+
alias_method :infra_name, :infra
|
7
|
+
alias_method :infra_name=, :infra=
|
8
|
+
|
9
|
+
def infra
|
10
|
+
@client.infra(infra_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def infra=(obj)
|
14
|
+
set_named(:infra, obj)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module VMCAppfog
|
2
|
+
class BindAll < VMC::CLI
|
3
|
+
desc "Bind all services in one app to another."
|
4
|
+
group :services, :manage
|
5
|
+
input :src_app, :desc => "Source application", :argument => :optional,
|
6
|
+
:from_given => by_name(:app)
|
7
|
+
input :dest_app, :desc => "Destination application", :argument => :optional,
|
8
|
+
:from_given => by_name(:app)
|
9
|
+
def bind_services
|
10
|
+
src_app = input[:src_app]
|
11
|
+
fail "No services to bind." if src_app.services.empty?
|
12
|
+
|
13
|
+
dest_app = input[:dest_app]
|
14
|
+
|
15
|
+
src_app.services.each do |service|
|
16
|
+
with_progress("Binding service #{c(service.name, :name)} to #{c(dest_app.name, :name)}") do |s|
|
17
|
+
if dest_app.binds?(service)
|
18
|
+
s.skip do
|
19
|
+
err "App #{b(dest_app.name)} already binds #{b(service.name)}."
|
20
|
+
end
|
21
|
+
else
|
22
|
+
dest_app.bind(service)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def ask_src_app
|
31
|
+
apps = client.apps
|
32
|
+
fail "No applications." if apps.empty?
|
33
|
+
|
34
|
+
ask("Which source application?", :choices => apps.sort_by(&:name),
|
35
|
+
:display => proc(&:name))
|
36
|
+
end
|
37
|
+
|
38
|
+
def ask_dest_app
|
39
|
+
apps = client.apps
|
40
|
+
fail "No applications." if apps.empty?
|
41
|
+
|
42
|
+
ask("Which destination application?", :choices => apps.sort_by(&:name),
|
43
|
+
:display => proc(&:name))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module VMCAppfog
|
2
|
+
class Clone < VMC::CLI
|
3
|
+
desc "Clone the application and services"
|
4
|
+
group :apps, :manage
|
5
|
+
input :src_app, :desc => "Source application", :argument => :optional,
|
6
|
+
:from_given => by_name(:app)
|
7
|
+
input :name, :desc => "Application name", :argument => :optional
|
8
|
+
input :infra, :desc => "Infrastructure to use", :from_given => by_name(:infra)
|
9
|
+
input :url, :desc => "Application url", :argument => :optional
|
10
|
+
input :nostart, :desc => "Do not start app", :default => false
|
11
|
+
def clone
|
12
|
+
src_app = input[:src_app]
|
13
|
+
dest_infra = input[:infra]
|
14
|
+
dest_app_name = input[:name, "#{src_app.name}-#{"%04x" % [rand(0x0100000)]}"]
|
15
|
+
app = client.app_by_name(dest_app_name)
|
16
|
+
fail "Application '#{dest_app_name}' already exists" unless app.nil?
|
17
|
+
dest_url = input[:url, "#{dest_app_name}.#{dest_infra.base}"]
|
18
|
+
|
19
|
+
# Start Clone
|
20
|
+
Dir.mktmpdir do |dir|
|
21
|
+
|
22
|
+
# Download source
|
23
|
+
zip_path = File.join(dir, src_app.name)
|
24
|
+
with_progress("Pulling last pushed source code") do
|
25
|
+
client.app_pull(src_app.name, zip_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
# manifest = {
|
29
|
+
# :name => "#{dest_appname}",
|
30
|
+
# :staging => app[:staging],
|
31
|
+
# :uris => [ url ],
|
32
|
+
# :instances => app[:instances],
|
33
|
+
# :resources => app[:resources]
|
34
|
+
# }
|
35
|
+
# manifest[:staging][:command] = app[:staging][:command] if app[:staging][:command]
|
36
|
+
# manifest[:infra] = { :provider => dest_infra.name } if dest_infra
|
37
|
+
|
38
|
+
dest_app = client.app
|
39
|
+
dest_app.name = dest_app_name
|
40
|
+
dest_app.infra = dest_infra
|
41
|
+
dest_app.url = dest_url
|
42
|
+
dest_app.uris = [dest_url]
|
43
|
+
dest_app.total_instances = 1
|
44
|
+
dest_app.framework = src_app.framework
|
45
|
+
dest_app.command = src_app.command unless src_app.command.nil?
|
46
|
+
dest_app.runtime = src_app.runtime
|
47
|
+
dest_app.memory = src_app.memory
|
48
|
+
dest_app.env = src_app.env
|
49
|
+
dest_app = filter(:create_app, dest_app)
|
50
|
+
with_progress("Creating #{c(dest_app.name, :name)}") do
|
51
|
+
dest_app.create!
|
52
|
+
end
|
53
|
+
|
54
|
+
# Upload source
|
55
|
+
with_progress("Uploading source to #{c(dest_app.name, :name)}") do
|
56
|
+
dest_app.upload(zip_path)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Clone services
|
60
|
+
src_app.services.each do |src_service|
|
61
|
+
|
62
|
+
# Export service data
|
63
|
+
export_info =
|
64
|
+
with_progress("Exporting service #{c(src_service.name, :name)}") do
|
65
|
+
client.export_service(src_service.name)
|
66
|
+
end
|
67
|
+
|
68
|
+
export_url = export_info[:uri]
|
69
|
+
|
70
|
+
# Create new service
|
71
|
+
cloned_service_name = generate_cloned_service_name(src_app.name, dest_app_name, src_service.name, dest_infra.name)
|
72
|
+
dest_service = client.service_instance
|
73
|
+
dest_service.infra_name = dest_infra.name
|
74
|
+
dest_service.name = cloned_service_name
|
75
|
+
dest_service.type = src_service.type
|
76
|
+
dest_service.vendor = src_service.vendor
|
77
|
+
dest_service.version = src_service.version.to_s
|
78
|
+
dest_service.tier = src_service.tier
|
79
|
+
with_progress("Creating service #{c(dest_service.name, :name)}") do
|
80
|
+
dest_service.create!
|
81
|
+
end
|
82
|
+
|
83
|
+
# Bind new service to app
|
84
|
+
with_progress("Binding service #{c(dest_service.name, :name)} to #{c(dest_app.name, :name)}") do
|
85
|
+
dest_app.bind(dest_service)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Import service data
|
89
|
+
import_info =
|
90
|
+
with_progress("Importing data to service #{c(dest_service.name, :name)}") do
|
91
|
+
client.import_service(dest_service.name, export_url)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
if !input[:nostart]
|
96
|
+
with_progress("Starting #{c(dest_app.name, :name)}") do
|
97
|
+
dest_app.start!
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def ask_url(default)
|
107
|
+
ask("New application url?", :default => default)
|
108
|
+
end
|
109
|
+
|
110
|
+
def ask_name(default)
|
111
|
+
ask("New application name?", :default => default)
|
112
|
+
end
|
113
|
+
|
114
|
+
def ask_infra
|
115
|
+
ask("Which Infrastructure?", :choices => client.infras,
|
116
|
+
:display => proc(&:name))
|
117
|
+
end
|
118
|
+
|
119
|
+
def generate_cloned_service_name(src_appname, dest_appname, src_servicename, dest_infra)
|
120
|
+
r = "%04x" % [rand(0x0100000)]
|
121
|
+
dest_servicename = src_servicename.sub(src_appname, dest_appname).sub(/-[0-9A-Fa-f]{4,5}/,"-#{r}")
|
122
|
+
if src_servicename == dest_servicename
|
123
|
+
if dest_infra
|
124
|
+
dest_servicename = "#{dest_servicename}-#{dest_infra}"
|
125
|
+
else
|
126
|
+
dest_servicename = "#{dest_servicename}-#{r}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
dest_servicename
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module VMCAppfog
|
2
|
+
class Download < VMC::CLI
|
3
|
+
desc "Downloads last pushed source to zipfile"
|
4
|
+
group :apps, :download
|
5
|
+
input :app, :desc => "Application to pull", :argument => :optional,
|
6
|
+
:from_given => by_name(:app)
|
7
|
+
input :path, :desc => "Path to store app"
|
8
|
+
def download
|
9
|
+
app = input[:app]
|
10
|
+
path = File.expand_path(input[:path] || "#{app.name}.zip")
|
11
|
+
with_progress("Downloading last pushed source code to #{c(path, :path)}") do
|
12
|
+
client.app_download(app.name, path)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def ask_app
|
17
|
+
apps = client.apps
|
18
|
+
fail "No applications." if apps.empty?
|
19
|
+
|
20
|
+
ask("Which application?", :choices => apps.sort_by(&:name),
|
21
|
+
:display => proc(&:name))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module VMCAppfog
|
2
|
+
class Export < VMC::CLI
|
3
|
+
desc "Export the data from a service"
|
4
|
+
group :services, :manage
|
5
|
+
input :service, :desc => "Service to export", :argument => :optional,
|
6
|
+
:from_given => by_name(:service_instance, "service")
|
7
|
+
def export_service
|
8
|
+
service = input[:export_service]
|
9
|
+
|
10
|
+
export_info =
|
11
|
+
with_progress("Exporting service #{c(service.name, :name)}") do
|
12
|
+
client.export_service(service.name)
|
13
|
+
end
|
14
|
+
|
15
|
+
line unless quiet?
|
16
|
+
|
17
|
+
line "#{c(service.name, :name)} exported to: #{export_info[:uri]}"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def ask_url
|
23
|
+
ask("Url to import from")
|
24
|
+
end
|
25
|
+
|
26
|
+
def ask_service
|
27
|
+
services = client.service_instances
|
28
|
+
fail "No services." if services.empty?
|
29
|
+
|
30
|
+
ask("Export which service?", :choices => services.sort_by(&:name),
|
31
|
+
:display => proc(&:name))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module VMCAppfog
|
2
|
+
class Frameworks < VMC::CLI
|
3
|
+
desc "List frameworks"
|
4
|
+
group :system
|
5
|
+
def frameworks
|
6
|
+
frameworks =
|
7
|
+
with_progress("Getting frameworks") do
|
8
|
+
client.frameworks
|
9
|
+
end
|
10
|
+
|
11
|
+
line unless quiet?
|
12
|
+
|
13
|
+
table(
|
14
|
+
%w{Name},
|
15
|
+
frameworks.collect { |r|
|
16
|
+
[c(r.name, :name),
|
17
|
+
]
|
18
|
+
})
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module VMCAppfog
|
2
|
+
class Import < VMC::CLI
|
3
|
+
desc "Import data from url"
|
4
|
+
group :services, :manage
|
5
|
+
input :service, :desc => "Service to import data to", :argument => :optional,
|
6
|
+
:from_given => by_name(:service_instance, "service")
|
7
|
+
input :url, :desc => "Data url to import", :argument => :optional
|
8
|
+
def import_service
|
9
|
+
service = input[:import_service]
|
10
|
+
url = input[:url]
|
11
|
+
|
12
|
+
import_info =
|
13
|
+
with_progress("Importing data to service #{c(service.name, :name)}") do
|
14
|
+
client.import_service(service.name, url)
|
15
|
+
end
|
16
|
+
|
17
|
+
line unless quiet?
|
18
|
+
|
19
|
+
line "Data imported to #{c(service.name, :name)} successfully "
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def ask_service
|
25
|
+
services = client.service_instances
|
26
|
+
fail "No services." if services.empty?
|
27
|
+
|
28
|
+
ask("Import to which service?", :choices => services.sort_by(&:name),
|
29
|
+
:display => proc(&:name))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module VMCAppfog
|
2
|
+
class Infras < VMC::CLI
|
3
|
+
desc "List infras"
|
4
|
+
group :system
|
5
|
+
input :space, :desc => "Show infras in given space",
|
6
|
+
:default => proc { client.current_space },
|
7
|
+
:from_given => by_name(:space)
|
8
|
+
def infras
|
9
|
+
if space = input[:space]
|
10
|
+
begin
|
11
|
+
space.summarize!
|
12
|
+
rescue CFoundry::APIError
|
13
|
+
end
|
14
|
+
|
15
|
+
infras =
|
16
|
+
with_progress("Getting infras in #{c(space.name, :name)}") do
|
17
|
+
space.infras
|
18
|
+
end
|
19
|
+
else
|
20
|
+
infras =
|
21
|
+
with_progress("Getting infras") do
|
22
|
+
client.infras
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
line unless quiet?
|
27
|
+
|
28
|
+
table(
|
29
|
+
%w{infra description},
|
30
|
+
infras.collect { |r|
|
31
|
+
[c(r.name, :infra),c(r.description, :description),
|
32
|
+
]
|
33
|
+
})
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module VMCAppfog
|
2
|
+
class Pull < VMC::CLI
|
3
|
+
desc "Downloads last pushed source to app name or path"
|
4
|
+
group :apps, :download
|
5
|
+
input :app, :desc => "Application to pull", :argument => :optional,
|
6
|
+
:from_given => by_name(:app)
|
7
|
+
input :path, :desc => "Path to store app"
|
8
|
+
def pull
|
9
|
+
app = input[:app]
|
10
|
+
path = File.expand_path(input[:path] || app.name)
|
11
|
+
|
12
|
+
with_progress("Pulling last pushed source code to #{c(app.name, :name)}") do
|
13
|
+
client.app_pull(app.name, path)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def ask_app
|
18
|
+
apps = client.apps
|
19
|
+
fail "No applications." if apps.empty?
|
20
|
+
|
21
|
+
ask("Which application?", :choices => apps.sort_by(&:name),
|
22
|
+
:display => proc(&:name))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module VMCAppfog
|
2
|
+
class Runtimes < VMC::CLI
|
3
|
+
desc "List runtimes"
|
4
|
+
group :system
|
5
|
+
def runtimes
|
6
|
+
runtimes =
|
7
|
+
with_progress("Getting runtimes") do
|
8
|
+
client.runtimes
|
9
|
+
end
|
10
|
+
|
11
|
+
line unless quiet?
|
12
|
+
|
13
|
+
table(
|
14
|
+
%w{runtime description},
|
15
|
+
runtimes.collect { |r|
|
16
|
+
[c(r.name, :name),c(r.description, :description),
|
17
|
+
]
|
18
|
+
})
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "mothership/help"
|
2
|
+
|
3
|
+
module Mothership::Help
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def insert_group(name, args)
|
7
|
+
index = 0
|
8
|
+
@@tree.each_with_index do |(key, value), i|
|
9
|
+
index = i
|
10
|
+
break if key == name
|
11
|
+
end
|
12
|
+
add_group(@@groups[index][:children], @@tree[name][:children], *args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
Mothership::Help.insert_group(:apps, [:download, "Download"])
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module CFoundry
|
2
|
+
class AuthToken
|
3
|
+
class << self
|
4
|
+
def from_cc_token(token_string)
|
5
|
+
new(token_string)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class BaseClient
|
11
|
+
def uaa
|
12
|
+
return @uaa unless @uaa.nil?
|
13
|
+
|
14
|
+
endpoint = info[:authorization_endpoint]
|
15
|
+
|
16
|
+
return @uaa = false unless endpoint
|
17
|
+
@uaa = CFoundry::UAAClient.new(endpoint)
|
18
|
+
@uaa.trace = @trace
|
19
|
+
@uaa.token = @token
|
20
|
+
@uaa
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module LoginHelpers
|
25
|
+
def login_prompts
|
26
|
+
if @base.uaa
|
27
|
+
@base.uaa.prompts
|
28
|
+
else
|
29
|
+
{
|
30
|
+
:username => %w[text Email],
|
31
|
+
:password => %w[password Password]
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def login(username, password)
|
37
|
+
token =
|
38
|
+
if @base.uaa
|
39
|
+
AuthToken.from_uaa_token_info(@base.uaa.authorize(username, password))
|
40
|
+
else
|
41
|
+
AuthToken.from_cc_token(@base.create_token({:password => password}, username)[:token])
|
42
|
+
end
|
43
|
+
|
44
|
+
@base.token = token
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "vmc/cli"
|
2
|
+
require "appfog-vmc-plugin/non_uaa"
|
3
|
+
require "appfog-vmc-plugin/cfoundry"
|
4
|
+
require "appfog-vmc-plugin/vmc"
|
5
|
+
require "appfog-vmc-plugin/help"
|
6
|
+
require "appfog-vmc-plugin/net_http"
|
7
|
+
|
8
|
+
command_files = "../deprecated/**/*.rb"
|
9
|
+
Dir[File.expand_path(command_files, __FILE__)].each do |file|
|
10
|
+
require file
|
11
|
+
end
|
12
|
+
|
13
|
+
command_files = "../commands/**/*.rb"
|
14
|
+
Dir[File.expand_path(command_files, __FILE__)].each do |file|
|
15
|
+
require file
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: appfog-vmc-plugin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tim Santeford
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: cfoundry
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.5.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.5.0
|
30
|
+
description:
|
31
|
+
email:
|
32
|
+
- tim@appfog.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- Rakefile
|
38
|
+
- lib/appfog-vmc-plugin/cfoundry/upload_helpers.rb
|
39
|
+
- lib/appfog-vmc-plugin/cfoundry/v1/app.rb
|
40
|
+
- lib/appfog-vmc-plugin/cfoundry/v1/base.rb
|
41
|
+
- lib/appfog-vmc-plugin/cfoundry/v1/client.rb
|
42
|
+
- lib/appfog-vmc-plugin/cfoundry/v1/infra.rb
|
43
|
+
- lib/appfog-vmc-plugin/cfoundry/v1/service.rb
|
44
|
+
- lib/appfog-vmc-plugin/cfoundry/v1/service_instance.rb
|
45
|
+
- lib/appfog-vmc-plugin/cfoundry.rb
|
46
|
+
- lib/appfog-vmc-plugin/commands/bind-all.rb
|
47
|
+
- lib/appfog-vmc-plugin/commands/clone.rb
|
48
|
+
- lib/appfog-vmc-plugin/commands/download.rb
|
49
|
+
- lib/appfog-vmc-plugin/commands/export.rb
|
50
|
+
- lib/appfog-vmc-plugin/commands/frameworks.rb
|
51
|
+
- lib/appfog-vmc-plugin/commands/import.rb
|
52
|
+
- lib/appfog-vmc-plugin/commands/infra.rb
|
53
|
+
- lib/appfog-vmc-plugin/commands/pull.rb
|
54
|
+
- lib/appfog-vmc-plugin/commands/runtimes.rb
|
55
|
+
- lib/appfog-vmc-plugin/help.rb
|
56
|
+
- lib/appfog-vmc-plugin/net_http.rb
|
57
|
+
- lib/appfog-vmc-plugin/non_uaa.rb
|
58
|
+
- lib/appfog-vmc-plugin/plugin.rb
|
59
|
+
- lib/appfog-vmc-plugin/version.rb
|
60
|
+
- lib/appfog-vmc-plugin/vmc/app/apps.rb
|
61
|
+
- lib/appfog-vmc-plugin/vmc.rb
|
62
|
+
homepage: http://www.appfog.com/
|
63
|
+
licenses: []
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubyforge_project: appfog-vmc-plugin
|
82
|
+
rubygems_version: 1.8.23
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: Clones applications between infras
|
86
|
+
test_files: []
|