cloulu 0.0.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/bin/{cloulu → cl} +0 -0
  2. data/lib/cc_api_stub/applications.rb +53 -0
  3. data/lib/cc_api_stub/domains.rb +16 -0
  4. data/lib/cc_api_stub/frameworks.rb +22 -0
  5. data/lib/cc_api_stub/helper.rb +131 -0
  6. data/lib/cc_api_stub/login.rb +21 -0
  7. data/lib/cc_api_stub/organization_users.rb +21 -0
  8. data/lib/cc_api_stub/organizations.rb +70 -0
  9. data/lib/cc_api_stub/routes.rb +26 -0
  10. data/lib/cc_api_stub/runtimes.rb +22 -0
  11. data/lib/cc_api_stub/service_bindings.rb +22 -0
  12. data/lib/cc_api_stub/service_instances.rb +22 -0
  13. data/lib/cc_api_stub/services.rb +25 -0
  14. data/lib/cc_api_stub/spaces.rb +49 -0
  15. data/lib/cc_api_stub/users.rb +84 -0
  16. data/lib/cc_api_stub.rb +17 -0
  17. data/lib/cfoundry/auth_token.rb +63 -0
  18. data/lib/cfoundry/baseclient.rb +201 -0
  19. data/lib/cfoundry/chatty_hash.rb +46 -0
  20. data/lib/cfoundry/client.rb +46 -0
  21. data/lib/cfoundry/concerns/login_helpers.rb +13 -0
  22. data/lib/cfoundry/errors.rb +160 -0
  23. data/lib/cfoundry/rest_client.rb +299 -0
  24. data/lib/cfoundry/test_support.rb +3 -0
  25. data/lib/cfoundry/trace_helpers.rb +40 -0
  26. data/lib/cfoundry/uaaclient.rb +112 -0
  27. data/lib/cfoundry/upload_helpers.rb +187 -0
  28. data/lib/cfoundry/v1/app.rb +363 -0
  29. data/lib/cfoundry/v1/base.rb +72 -0
  30. data/lib/cfoundry/v1/client.rb +193 -0
  31. data/lib/cfoundry/v1/framework.rb +21 -0
  32. data/lib/cfoundry/v1/model.rb +178 -0
  33. data/lib/cfoundry/v1/model_magic.rb +129 -0
  34. data/lib/cfoundry/v1/runtime.rb +24 -0
  35. data/lib/cfoundry/v1/service.rb +39 -0
  36. data/lib/cfoundry/v1/service_instance.rb +32 -0
  37. data/lib/cfoundry/v1/service_plan.rb +19 -0
  38. data/lib/cfoundry/v1/user.rb +22 -0
  39. data/lib/cfoundry/v2/app.rb +392 -0
  40. data/lib/cfoundry/v2/base.rb +83 -0
  41. data/lib/cfoundry/v2/client.rb +138 -0
  42. data/lib/cfoundry/v2/domain.rb +11 -0
  43. data/lib/cfoundry/v2/framework.rb +14 -0
  44. data/lib/cfoundry/v2/model.rb +148 -0
  45. data/lib/cfoundry/v2/model_magic.rb +449 -0
  46. data/lib/cfoundry/v2/organization.rb +16 -0
  47. data/lib/cfoundry/v2/route.rb +15 -0
  48. data/lib/cfoundry/v2/runtime.rb +12 -0
  49. data/lib/cfoundry/v2/service.rb +19 -0
  50. data/lib/cfoundry/v2/service_auth_token.rb +9 -0
  51. data/lib/cfoundry/v2/service_binding.rb +10 -0
  52. data/lib/cfoundry/v2/service_instance.rb +14 -0
  53. data/lib/cfoundry/v2/service_plan.rb +12 -0
  54. data/lib/cfoundry/v2/space.rb +18 -0
  55. data/lib/cfoundry/v2/user.rb +64 -0
  56. data/lib/cfoundry/validator.rb +39 -0
  57. data/lib/cfoundry/version.rb +4 -0
  58. data/lib/cfoundry/zip.rb +56 -0
  59. data/lib/cfoundry.rb +2 -0
  60. data/lib/manifests-vmc-plugin/errors.rb +21 -0
  61. data/lib/manifests-vmc-plugin/loader/builder.rb +34 -0
  62. data/lib/manifests-vmc-plugin/loader/normalizer.rb +149 -0
  63. data/lib/manifests-vmc-plugin/loader/resolver.rb +79 -0
  64. data/lib/manifests-vmc-plugin/loader.rb +31 -0
  65. data/lib/manifests-vmc-plugin/plugin.rb +145 -0
  66. data/lib/manifests-vmc-plugin/version.rb +3 -0
  67. data/lib/manifests-vmc-plugin.rb +313 -0
  68. data/lib/mothership/base.rb +99 -0
  69. data/lib/mothership/callbacks.rb +85 -0
  70. data/lib/mothership/command.rb +146 -0
  71. data/lib/mothership/errors.rb +38 -0
  72. data/lib/mothership/help/commands.rb +53 -0
  73. data/lib/mothership/help/printer.rb +170 -0
  74. data/lib/mothership/help.rb +64 -0
  75. data/lib/mothership/inputs.rb +189 -0
  76. data/lib/mothership/parser.rb +182 -0
  77. data/lib/mothership/version.rb +3 -0
  78. data/lib/mothership.rb +64 -0
  79. data/lib/tunnel-vmc-plugin/plugin.rb +178 -0
  80. data/lib/tunnel-vmc-plugin/tunnel.rb +308 -0
  81. data/lib/tunnel-vmc-plugin/version.rb +3 -0
  82. data/lib/uaa/http.rb +168 -0
  83. data/lib/uaa/misc.rb +121 -0
  84. data/lib/uaa/scim.rb +292 -0
  85. data/lib/uaa/token_coder.rb +196 -0
  86. data/lib/uaa/token_issuer.rb +255 -0
  87. data/lib/uaa/util.rb +235 -0
  88. data/lib/uaa/version.rb +19 -0
  89. data/lib/uaa.rb +18 -0
  90. data/lib/vmc/cli/app/app.rb +45 -0
  91. data/lib/vmc/cli/app/apps.rb +99 -0
  92. data/lib/vmc/cli/app/base.rb +90 -0
  93. data/lib/vmc/cli/app/crashes.rb +42 -0
  94. data/lib/vmc/cli/app/delete.rb +95 -0
  95. data/lib/vmc/cli/app/deprecated.rb +11 -0
  96. data/lib/vmc/cli/app/env.rb +78 -0
  97. data/lib/vmc/cli/app/files.rb +137 -0
  98. data/lib/vmc/cli/app/health.rb +26 -0
  99. data/lib/vmc/cli/app/instances.rb +53 -0
  100. data/lib/vmc/cli/app/logs.rb +76 -0
  101. data/lib/vmc/cli/app/push/create.rb +165 -0
  102. data/lib/vmc/cli/app/push/interactions.rb +94 -0
  103. data/lib/vmc/cli/app/push/sync.rb +64 -0
  104. data/lib/vmc/cli/app/push.rb +109 -0
  105. data/lib/vmc/cli/app/rename.rb +35 -0
  106. data/lib/vmc/cli/app/restart.rb +20 -0
  107. data/lib/vmc/cli/app/scale.rb +71 -0
  108. data/lib/vmc/cli/app/start.rb +143 -0
  109. data/lib/vmc/cli/app/stats.rb +67 -0
  110. data/lib/vmc/cli/app/stop.rb +27 -0
  111. data/lib/vmc/cli/help.rb +11 -0
  112. data/lib/vmc/cli/interactive.rb +105 -0
  113. data/lib/vmc/cli/route/base.rb +12 -0
  114. data/lib/vmc/cli/route/map.rb +82 -0
  115. data/lib/vmc/cli/route/routes.rb +25 -0
  116. data/lib/vmc/cli/route/unmap.rb +94 -0
  117. data/lib/vmc/cli/service/base.rb +8 -0
  118. data/lib/vmc/cli/service/bind.rb +44 -0
  119. data/lib/vmc/cli/service/create.rb +126 -0
  120. data/lib/vmc/cli/service/delete.rb +86 -0
  121. data/lib/vmc/cli/service/rename.rb +35 -0
  122. data/lib/vmc/cli/service/service.rb +42 -0
  123. data/lib/vmc/cli/service/services.rb +114 -0
  124. data/lib/vmc/cli/service/unbind.rb +38 -0
  125. data/lib/vmc/cli/start/base.rb +94 -0
  126. data/lib/vmc/cli/start/colors.rb +13 -0
  127. data/lib/vmc/cli/start/info.rb +126 -0
  128. data/lib/vmc/cli/start/login.rb +97 -0
  129. data/lib/vmc/cli/start/logout.rb +17 -0
  130. data/lib/vmc/cli/start/target.rb +60 -0
  131. data/lib/vmc/cli/start/target_interactions.rb +37 -0
  132. data/lib/vmc/cli/start/targets.rb +16 -0
  133. data/lib/vmc/cli/user/base.rb +29 -0
  134. data/lib/vmc/cli/user/create.rb +39 -0
  135. data/lib/vmc/cli/user/delete.rb +27 -0
  136. data/lib/vmc/cli/user/passwd.rb +50 -0
  137. data/lib/vmc/cli/user/register.rb +42 -0
  138. data/lib/vmc/cli/user/users.rb +32 -0
  139. data/lib/vmc/cli/v2_check_cli.rb +16 -0
  140. data/lib/vmc/cli.rb +474 -0
  141. data/lib/vmc/constants.rb +13 -0
  142. data/lib/vmc/detect.rb +129 -0
  143. data/lib/vmc/errors.rb +19 -0
  144. data/lib/vmc/plugin.rb +56 -0
  145. data/lib/vmc/spacing.rb +89 -0
  146. data/lib/vmc/spec_helper.rb +1 -0
  147. data/lib/vmc/test_support.rb +6 -0
  148. data/lib/vmc/version.rb +3 -0
  149. data/lib/vmc.rb +8 -0
  150. data/vendor/errors/v1.yml +189 -0
  151. data/vendor/errors/v2.yml +360 -0
  152. metadata +303 -190
@@ -0,0 +1,18 @@
1
+ require "cfoundry/v2/model"
2
+
3
+ module CFoundry::V2
4
+ class Space < Model
5
+ attribute :name, :string
6
+ to_one :organization
7
+ to_many :developers, :as => :user
8
+ to_many :managers, :as => :user
9
+ to_many :auditors, :as => :user
10
+ to_many :apps
11
+ to_many :domains
12
+ to_many :service_instances
13
+
14
+ scoped_to_organization
15
+
16
+ queryable_by :name, :organization_guid, :developer_guid, :app_guid
17
+ end
18
+ end
@@ -0,0 +1,64 @@
1
+ require "cfoundry/v2/model"
2
+
3
+ module CFoundry::V2
4
+ class User < Model
5
+ to_many :spaces
6
+ to_many :organizations
7
+ to_many :managed_organizations, :as => :organization
8
+ to_many :billing_managed_organizations, :as => :organization
9
+ to_many :audited_organizations, :as => :organization
10
+ to_many :managed_spaces, :as => :space
11
+ to_many :audited_spaces, :as => :space
12
+ attribute :admin, :boolean
13
+ to_one :default_space, :as => :space
14
+
15
+ attribute :guid, :string # guid is explicitly set for users
16
+
17
+ queryable_by :space_guid, :organization_guid, :managed_organization_guid,
18
+ :billing_managed_organization_guid, :audited_organization_guid,
19
+ :managed_space_guid, :audited_space_guid
20
+
21
+ def guid
22
+ @guid
23
+ end
24
+
25
+ alias set_guid_attribute guid=
26
+
27
+ def guid=(x)
28
+ @guid = x
29
+ set_guid_attribute(x)
30
+ end
31
+
32
+ alias :admin? :admin
33
+
34
+ def change_password!(new, old)
35
+ @client.base.uaa.change_password(@guid, new, old)
36
+ end
37
+
38
+ # optional metadata from UAA
39
+ attr_accessor :emails, :name
40
+
41
+ def email
42
+ return unless @emails && @emails.first
43
+ @emails.first[:value]
44
+ end
45
+
46
+ def given_name
47
+ return unless @name && @name[:givenName] != email
48
+ @name[:givenName]
49
+ end
50
+
51
+ def family_name
52
+ return unless @name && @name[:familyName] != email
53
+ @name[:familyName]
54
+ end
55
+
56
+ def full_name
57
+ if @name && @name[:fullName]
58
+ @name[:fullName]
59
+ elsif given_name && family_name
60
+ "#{given_name} #{family_name}"
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,39 @@
1
+ module CFoundry
2
+ module Validator
3
+ class << self
4
+ def value_matches?(val, type)
5
+ case type
6
+ when Class
7
+ val.is_a?(type)
8
+ when Regexp
9
+ val.is_a?(String) && val =~ type
10
+ when :url
11
+ value_matches?(val, URI::regexp(%w(http https)))
12
+ when :https_url
13
+ value_matches?(val, URI::regexp("https"))
14
+ when :boolean
15
+ val.is_a?(TrueClass) || val.is_a?(FalseClass)
16
+ when Array
17
+ val.all? do |x|
18
+ value_matches?(x, type.first)
19
+ end
20
+ when Hash
21
+ val.is_a?(Hash) &&
22
+ type.all? { |name, subtype|
23
+ val.key?(name) && value_matches?(val[name], subtype)
24
+ }
25
+ when nil
26
+ true
27
+ else
28
+ val.is_a?(Object.const_get(type.to_s.capitalize))
29
+ end
30
+ end
31
+
32
+ def validate_type(val, type)
33
+ unless value_matches?(val, type)
34
+ raise CFoundry::Mismatch.new(type, val)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,4 @@
1
+ module CFoundry # :nodoc:
2
+ # CFoundry library version number.
3
+ VERSION = "0.5.2".freeze
4
+ end
@@ -0,0 +1,56 @@
1
+ require "zip/zipfilesystem"
2
+
3
+ module CFoundry
4
+ # Generic Zpi API. Uses rubyzip underneath, but may be changed in the future
5
+ # to use system zip command if necessary.
6
+ module Zip
7
+ # Directory entries to exclude from packing.
8
+ PACK_EXCLUSION_GLOBS = %w(.. . *~ #*# *.log)
9
+
10
+ module_function
11
+
12
+ # Get the entries in the zip file. Returns an array of the entire
13
+ # contents, recursively (not just top-level).
14
+ def entry_lines(file)
15
+ entries = []
16
+ ::Zip::ZipFile.foreach(file) do |zentry|
17
+ entries << zentry
18
+ end
19
+ entries
20
+ end
21
+
22
+ # Unpack a zip +file+ to directory +dest+.
23
+ def unpack(file, dest)
24
+ ::Zip::ZipFile.foreach(file) do |zentry|
25
+ epath = "#{dest}/#{zentry}"
26
+ dirname = File.dirname(epath)
27
+ FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
28
+ zentry.extract(epath) unless File.exists?(epath)
29
+ end
30
+ end
31
+
32
+ # Determine what files in +dir+ to pack.
33
+ def files_to_pack(dir)
34
+ Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).select do |f|
35
+ File.exists?(f) &&
36
+ PACK_EXCLUSION_GLOBS.none? do |e|
37
+ File.fnmatch(e, File.basename(f))
38
+ end
39
+ end
40
+ end
41
+
42
+ # Package directory +dir+ as file +zipfile+.
43
+ def pack(dir, zipfile)
44
+ files = files_to_pack(dir)
45
+ return false if files.empty?
46
+
47
+ ::Zip::ZipFile.open(zipfile, true) do |zf|
48
+ files.each do |f|
49
+ zf.add(f.sub("#{dir}/",''), f)
50
+ end
51
+ end
52
+
53
+ true
54
+ end
55
+ end
56
+ end
data/lib/cfoundry.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "cfoundry/version"
2
+ require "cfoundry/client"
@@ -0,0 +1,21 @@
1
+ module VMCManifests
2
+ class CircularDependency < RuntimeError
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def to_s
8
+ "Circular dependency in application '#@app'"
9
+ end
10
+ end
11
+
12
+ class UnknownSymbol < RuntimeError
13
+ def initialize(sym)
14
+ @sym = sym
15
+ end
16
+
17
+ def to_s
18
+ "Undefined symbol in manifest: '#@sym'"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ module VMCManifests
2
+ module Builder
3
+ # parse a manifest and merge with its inherited manifests
4
+ def build(file)
5
+ manifest = YAML.load_file file
6
+
7
+ Array(manifest["inherit"]).each do |path|
8
+ manifest = merge_parent(path, manifest)
9
+ end
10
+
11
+ manifest
12
+ end
13
+
14
+ private
15
+
16
+ # merge the manifest at `parent_path' into the `child'
17
+ def merge_parent(parent_path, child)
18
+ merge_manifest(build(from_manifest(parent_path)), child)
19
+ end
20
+
21
+ # deep hash merge
22
+ def merge_manifest(parent, child)
23
+ merge = proc do |_, old, new|
24
+ if new.is_a?(Hash) && old.is_a?(Hash)
25
+ old.merge(new, &merge)
26
+ else
27
+ new
28
+ end
29
+ end
30
+
31
+ parent.merge(child, &merge)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,149 @@
1
+ module VMCManifests
2
+ module Normalizer
3
+ MANIFEST_META = ["applications", "properties"]
4
+
5
+ def normalize!(manifest)
6
+ toplevel = toplevel_attributes(manifest)
7
+
8
+ apps = manifest["applications"]
9
+ apps ||= [{}]
10
+
11
+ default_paths_to_keys!(apps)
12
+
13
+ apps = convert_to_array(apps)
14
+
15
+ merge_toplevel!(toplevel, manifest, apps)
16
+ normalize_apps!(apps)
17
+
18
+ manifest["applications"] = apps
19
+
20
+ normalize_paths!(apps)
21
+
22
+ keyval = normalize_key_val(manifest)
23
+ manifest.clear.merge!(keyval)
24
+
25
+ nil
26
+ end
27
+
28
+ private
29
+
30
+ def normalize_paths!(apps)
31
+ apps.each do |app|
32
+ app["path"] = from_manifest(app["path"])
33
+ end
34
+ end
35
+
36
+ def convert_to_array(apps)
37
+ return apps if apps.is_a?(Array)
38
+
39
+ ordered_by_deps(apps)
40
+ end
41
+
42
+ # sort applications in dependency order
43
+ # e.g. if A depends on B, B will be listed before A
44
+ def ordered_by_deps(apps, processed = Set[])
45
+ ordered = []
46
+ apps.each do |tag, info|
47
+ next if processed.include?(tag)
48
+
49
+ if deps = Array(info["depends-on"])
50
+ dep_apps = {}
51
+ deps.each do |dep|
52
+ dep_apps[dep] = apps[dep]
53
+ end
54
+
55
+ processed.add(tag)
56
+
57
+ ordered += ordered_by_deps(dep_apps, processed)
58
+ ordered << info
59
+ else
60
+ ordered << info
61
+ processed.add(tag)
62
+ end
63
+ end
64
+
65
+ ordered.each { |app| app.delete("depends-on") }
66
+
67
+ ordered
68
+ end
69
+
70
+ def default_paths_to_keys!(apps)
71
+ return if apps.is_a?(Array)
72
+
73
+ apps.each do |tag, app|
74
+ app["path"] ||= tag
75
+ end
76
+ end
77
+
78
+ def normalize_apps!(apps)
79
+ apps.each do |app|
80
+ normalize_app!(app)
81
+ end
82
+ end
83
+
84
+ def merge_toplevel!(toplevel, manifest, apps)
85
+ return if toplevel.empty?
86
+
87
+ apps.collect! do |a|
88
+ toplevel.merge(a)
89
+ end
90
+
91
+ toplevel.each do |k, _|
92
+ manifest.delete k
93
+ end
94
+ end
95
+
96
+ def normalize_app!(app)
97
+ if app["framework"].is_a?(Hash)
98
+ app["framework"] = app["framework"]["name"]
99
+ end
100
+
101
+ if app.key?("mem")
102
+ app["memory"] = app.delete("mem")
103
+ end
104
+
105
+ if app.key?("url") && app["url"].nil?
106
+ app["url"] = "none"
107
+ end
108
+
109
+ if app.key?("subdomain")
110
+ if app.key?("host")
111
+ app.delete("subdomain")
112
+ else
113
+ app["host"] = app.delete("subdomain")
114
+ end
115
+ end
116
+ end
117
+
118
+ def toplevel_attributes(manifest)
119
+ top =
120
+ manifest.reject { |k, _|
121
+ MANIFEST_META.include? k
122
+ }
123
+
124
+ # implicit toplevel path of .
125
+ top["path"] ||= "."
126
+
127
+ top
128
+ end
129
+
130
+ def normalize_key_val(val)
131
+ case val
132
+ when Hash
133
+ stringified = {}
134
+
135
+ val.each do |k, v|
136
+ stringified[k.to_sym] = normalize_key_val(v)
137
+ end
138
+
139
+ stringified
140
+ when Array
141
+ val.collect { |x| normalize_key_val(x) }
142
+ when nil
143
+ nil
144
+ else
145
+ val.to_s
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,79 @@
1
+ module VMCManifests
2
+ module Resolver
3
+ def resolve(manifest, resolver)
4
+ new = {}
5
+
6
+ new[:applications] = manifest[:applications].collect do |app|
7
+ resolve_lexically(resolver, app, [manifest])
8
+ end
9
+
10
+ resolve_lexically(resolver, new, [new])
11
+ end
12
+
13
+ private
14
+
15
+ # resolve symbols, with hashes introducing new lexical symbols
16
+ def resolve_lexically(resolver, val, ctx)
17
+ case val
18
+ when Hash
19
+ new = {}
20
+
21
+ val.each do |k, v|
22
+ new[k] = resolve_lexically(resolver, v, [val] + ctx)
23
+ end
24
+
25
+ new
26
+ when Array
27
+ val.collect do |v|
28
+ resolve_lexically(resolver, v, ctx)
29
+ end
30
+ when String
31
+ val.gsub(/\$\{([^\}]+)\}/) do
32
+ resolve_symbol(resolver, $1, ctx)
33
+ end
34
+ else
35
+ val
36
+ end
37
+ end
38
+
39
+ # resolve a symbol to its value, and then resolve that value
40
+ def resolve_symbol(resolver, sym, ctx)
41
+ if found = find_symbol(sym.to_sym, ctx)
42
+ resolve_lexically(resolver, found, ctx)
43
+ found
44
+ elsif dynamic = resolver.resolve_symbol(sym)
45
+ dynamic
46
+ else
47
+ fail("Unknown symbol in manifest: #{sym}")
48
+ end
49
+ end
50
+
51
+ # search for a symbol introduced in the lexical context
52
+ def find_symbol(sym, ctx)
53
+ ctx.each do |h|
54
+ if val = resolve_in(h, sym)
55
+ return val
56
+ end
57
+ end
58
+
59
+ nil
60
+ end
61
+
62
+ # find a value, searching in explicit properties first
63
+ def resolve_in(hash, *where)
64
+ find_in_hash(hash, [:properties] + where) ||
65
+ find_in_hash(hash, where)
66
+ end
67
+
68
+ # helper for following a path of values in a hash
69
+ def find_in_hash(hash, where)
70
+ what = hash
71
+ where.each do |x|
72
+ return nil unless what.is_a?(Hash)
73
+ what = what[x]
74
+ end
75
+
76
+ what
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,31 @@
1
+ require "manifests-vmc-plugin/loader/builder"
2
+ require "manifests-vmc-plugin/loader/normalizer"
3
+ require "manifests-vmc-plugin/loader/resolver"
4
+
5
+ module VMCManifests
6
+ class Loader
7
+ include Builder
8
+ include Normalizer
9
+ include Resolver
10
+
11
+ def initialize(file, resolver)
12
+ @file = file
13
+ @resolver = resolver
14
+ end
15
+
16
+ def manifest
17
+ info = build(@file)
18
+ normalize! info
19
+ resolve info, @resolver
20
+ end
21
+
22
+ private
23
+
24
+ # expand a path relative to the manifest file's directory
25
+ def from_manifest(path)
26
+ return path unless @file
27
+
28
+ File.expand_path(path, File.dirname(@file))
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,145 @@
1
+ require "pathname"
2
+
3
+ require "vmc/plugin"
4
+ require "manifests-vmc-plugin"
5
+
6
+
7
+ class ManifestsPlugin < VMC::App::Base
8
+ include VMCManifests
9
+
10
+ option :manifest, :aliases => "-m", :value => :file,
11
+ :desc => "Path to manifest file to use"
12
+
13
+
14
+ [ :start, :restart, :instances, :logs, :env, :health, :stats,
15
+ :scale, :app, :stop, :delete
16
+ ].each do |wrap|
17
+ name_made_optional = change_argument(wrap, :app, :optional)
18
+
19
+ around(wrap) do |cmd, input|
20
+ wrap_with_optional_name(name_made_optional, cmd, input)
21
+ end
22
+ end
23
+
24
+
25
+ add_input :push, :reset, :desc => "Reset to values in the manifest",
26
+ :default => false
27
+
28
+ around(:push) do |push, input|
29
+ wrap_push(push, input)
30
+ end
31
+
32
+ private
33
+
34
+ def wrap_with_optional_name(name_made_optional, cmd, input)
35
+ return cmd.call if input[:all]
36
+
37
+ unless manifest
38
+ # if the command knows how to handle this
39
+ if input.has?(:app) || !name_made_optional
40
+ return cmd.call
41
+ else
42
+ return no_apps
43
+ end
44
+ end
45
+
46
+ internal, external = apps_in_manifest(input)
47
+
48
+ return cmd.call if internal.empty? && !external.empty?
49
+
50
+ show_manifest_usage
51
+
52
+ if internal.empty? && external.empty?
53
+ internal = current_apps if internal.empty?
54
+ internal = all_apps if internal.empty?
55
+ end
56
+
57
+ internal = internal.collect { |app| app[:name] }
58
+
59
+ apps = internal + external
60
+ return no_apps if apps.empty?
61
+
62
+ apps.each.with_index do |app, num|
63
+ line unless quiet? || num == 0
64
+ cmd.call(input.without(:apps).merge_given(:app => app))
65
+ end
66
+ end
67
+
68
+ def apply_changes(app, input)
69
+ app.memory = megabytes(input[:memory]) if input.has?(:memory)
70
+ app.total_instances = input[:instances] if input.has?(:instances)
71
+ app.command = input[:command] if input.has?(:command)
72
+ app.production = input[:plan].upcase.start_with?("P") if input.has?(:plan)
73
+ app.framework = input[:framework] if input.has?(:framework)
74
+ app.runtime = input[:runtime] if input.has?(:runtime)
75
+ app.buildpack = input[:buildpack] if input.has?(:buildpack)
76
+ end
77
+
78
+ def wrap_push(push, input)
79
+ unless manifest
80
+ create_and_save_manifest(push, input)
81
+ return
82
+ end
83
+
84
+ particular, external = apps_in_manifest(input)
85
+
86
+ unless external.empty?
87
+ fail "Could not find #{b(external.join(", "))}' in the manifest."
88
+ end
89
+
90
+ apps = particular.empty? ? all_apps : particular
91
+
92
+ show_manifest_usage
93
+
94
+ spaced(apps) do |app_manifest|
95
+ push_with_manifest(app_manifest, push, input)
96
+ end
97
+ end
98
+
99
+ def push_with_manifest(app_manifest, push, input)
100
+ with_filters(
101
+ :push => {
102
+ :create_app => proc { |a|
103
+ setup_env(a, app_manifest)
104
+ a
105
+ },
106
+ :push_app => proc { |a|
107
+ setup_services(a, app_manifest)
108
+ a
109
+ }
110
+ }) do
111
+ app_input = push_input_for(app_manifest, input)
112
+
113
+ push.call(app_input)
114
+ end
115
+ end
116
+
117
+ def push_input_for(app_manifest, input)
118
+ existing_app = client.app_by_name(app_manifest[:name])
119
+ rebased_input = input.rebase_given(app_manifest)
120
+
121
+ if !existing_app || input[:reset]
122
+ input = rebased_input
123
+ else
124
+ warn_reset_changes if manifest_differs?(existing_app, rebased_input)
125
+ end
126
+
127
+ input.merge(
128
+ :path => from_manifest(app_manifest[:path]),
129
+ :name => app_manifest[:name],
130
+ :bind_services => false,
131
+ :create_services => false)
132
+ end
133
+
134
+ def manifest_differs?(app, input)
135
+ apply_changes(app, input)
136
+ app.changed?
137
+ end
138
+
139
+ def create_and_save_manifest(push, input)
140
+ with_filters(
141
+ :push => { :push_app => proc { |a| ask_to_save(input, a); a } }) do
142
+ push.call
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,3 @@
1
+ module VMCManifests
2
+ VERSION = "0.6.2".freeze
3
+ end