ncfoundry 4.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +2 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +11 -0
  8. data/Checkfile +2 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE +987 -0
  11. data/NOTICE +10 -0
  12. data/README.md +9 -0
  13. data/Rakefile +14 -0
  14. data/VERSION +1 -0
  15. data/cfoundry.gemspec +41 -0
  16. data/config/locales/en.yml +168 -0
  17. data/lib/cc_api_stub/app_usage_events.rb +11 -0
  18. data/lib/cc_api_stub/applications.rb +57 -0
  19. data/lib/cc_api_stub/domains.rb +32 -0
  20. data/lib/cc_api_stub/events.rb +11 -0
  21. data/lib/cc_api_stub/frameworks.rb +22 -0
  22. data/lib/cc_api_stub/helper.rb +148 -0
  23. data/lib/cc_api_stub/login.rb +21 -0
  24. data/lib/cc_api_stub/organization_users.rb +27 -0
  25. data/lib/cc_api_stub/organizations.rb +82 -0
  26. data/lib/cc_api_stub/routes.rb +26 -0
  27. data/lib/cc_api_stub/runtimes.rb +22 -0
  28. data/lib/cc_api_stub/service_bindings.rb +22 -0
  29. data/lib/cc_api_stub/service_instances.rb +22 -0
  30. data/lib/cc_api_stub/services.rb +21 -0
  31. data/lib/cc_api_stub/space_users.rb +27 -0
  32. data/lib/cc_api_stub/spaces.rb +58 -0
  33. data/lib/cc_api_stub/users.rb +85 -0
  34. data/lib/cc_api_stub.rb +20 -0
  35. data/lib/cfoundry/auth_token.rb +62 -0
  36. data/lib/cfoundry/baseclient.rb +220 -0
  37. data/lib/cfoundry/chatty_hash.rb +46 -0
  38. data/lib/cfoundry/client.rb +42 -0
  39. data/lib/cfoundry/concerns/login_helpers.rb +14 -0
  40. data/lib/cfoundry/concerns/proxy_options.rb +14 -0
  41. data/lib/cfoundry/errors.rb +163 -0
  42. data/lib/cfoundry/rest_client.rb +316 -0
  43. data/lib/cfoundry/test_support.rb +3 -0
  44. data/lib/cfoundry/trace_helpers.rb +64 -0
  45. data/lib/cfoundry/uaaclient.rb +151 -0
  46. data/lib/cfoundry/upload_helpers.rb +222 -0
  47. data/lib/cfoundry/v2/app.rb +313 -0
  48. data/lib/cfoundry/v2/app_event.rb +13 -0
  49. data/lib/cfoundry/v2/app_instance.rb +74 -0
  50. data/lib/cfoundry/v2/app_usage_event.rb +14 -0
  51. data/lib/cfoundry/v2/base.rb +112 -0
  52. data/lib/cfoundry/v2/client.rb +104 -0
  53. data/lib/cfoundry/v2/domain.rb +20 -0
  54. data/lib/cfoundry/v2/event.rb +17 -0
  55. data/lib/cfoundry/v2/helper.rb +11 -0
  56. data/lib/cfoundry/v2/managed_service_instance.rb +13 -0
  57. data/lib/cfoundry/v2/model.rb +213 -0
  58. data/lib/cfoundry/v2/model_magic/attribute.rb +49 -0
  59. data/lib/cfoundry/v2/model_magic/client_extensions.rb +170 -0
  60. data/lib/cfoundry/v2/model_magic/has_summary.rb +49 -0
  61. data/lib/cfoundry/v2/model_magic/query_multi_value_helper.rb +21 -0
  62. data/lib/cfoundry/v2/model_magic/query_value_helper.rb +33 -0
  63. data/lib/cfoundry/v2/model_magic/queryable_by.rb +39 -0
  64. data/lib/cfoundry/v2/model_magic/to_many.rb +145 -0
  65. data/lib/cfoundry/v2/model_magic/to_one.rb +81 -0
  66. data/lib/cfoundry/v2/model_magic.rb +134 -0
  67. data/lib/cfoundry/v2/organization.rb +44 -0
  68. data/lib/cfoundry/v2/quota_definition.rb +12 -0
  69. data/lib/cfoundry/v2/route.rb +25 -0
  70. data/lib/cfoundry/v2/service.rb +22 -0
  71. data/lib/cfoundry/v2/service_auth_token.rb +9 -0
  72. data/lib/cfoundry/v2/service_binding.rb +10 -0
  73. data/lib/cfoundry/v2/service_broker.rb +12 -0
  74. data/lib/cfoundry/v2/service_instance.rb +14 -0
  75. data/lib/cfoundry/v2/service_plan.rb +16 -0
  76. data/lib/cfoundry/v2/space.rb +31 -0
  77. data/lib/cfoundry/v2/stack.rb +10 -0
  78. data/lib/cfoundry/v2/user.rb +97 -0
  79. data/lib/cfoundry/v2/user_provided_service_instance.rb +16 -0
  80. data/lib/cfoundry/validator.rb +41 -0
  81. data/lib/cfoundry/version.rb +4 -0
  82. data/lib/cfoundry/zip.rb +56 -0
  83. data/lib/cfoundry.rb +6 -0
  84. data/release_notes/release_1_5_3.md +177 -0
  85. data/release_notes/release_2.3.1.md +14 -0
  86. data/release_notes/release_2.3.3.md +38 -0
  87. data/release_notes/release_2.3.4.md +16 -0
  88. data/release_notes/release_2.3.5.md +14 -0
  89. data/release_notes/release_2.3.6.md +14 -0
  90. data/release_notes/release_2.3.6.rc1.md +29 -0
  91. data/release_notes/release_2.3.6.rc2.md +19 -0
  92. data/release_notes/release_2.3.7.rc1.md +14 -0
  93. data/release_notes/release_2.4.0.md +41 -0
  94. data/release_notes/release_2.4.1.rc1.md +58 -0
  95. data/release_notes/release_3.0.0.md +21 -0
  96. data/release_notes/release_3.0.1.md +16 -0
  97. data/release_notes/release_3.0.2.rc1.md +19 -0
  98. data/release_notes/release_4.0.0.md +19 -0
  99. data/release_notes/release_4.0.1.md +14 -0
  100. data/release_notes/release_4.0.2.rc1.md +14 -0
  101. data/release_notes/release_4.0.2.rc2.md +11 -0
  102. data/release_notes/release_4.0.2.rc3.md +11 -0
  103. data/release_notes/release_4.0.2.rc4.md +19 -0
  104. data/release_notes/release_4.0.2.rc5.md +14 -0
  105. data/release_notes/release_4.0.3.md +19 -0
  106. data/release_notes/release_4.0.4.rc1.md +14 -0
  107. data/release_notes/release_4.0.4.rc2.md +14 -0
  108. data/release_notes/release_4.1.0.md +19 -0
  109. data/release_notes/release_4.2.0.rc.md +24 -0
  110. data/release_notes/release_4.3.0.md +22 -0
  111. data/release_notes/release_4.3.1.md +14 -0
  112. data/release_notes/release_4.3.10.md +14 -0
  113. data/release_notes/release_4.3.11.md +14 -0
  114. data/release_notes/release_4.3.12.md +14 -0
  115. data/release_notes/release_4.3.2.rc1.md +21 -0
  116. data/release_notes/release_4.3.3.md +24 -0
  117. data/release_notes/release_4.3.4.md +11 -0
  118. data/release_notes/release_4.3.4.rc1.md +24 -0
  119. data/release_notes/release_4.3.5.md +36 -0
  120. data/release_notes/release_4.3.5.rc1.md +21 -0
  121. data/release_notes/release_4.3.6.md +14 -0
  122. data/release_notes/release_4.3.7.md +50 -0
  123. data/release_notes/release_4.3.8.md +19 -0
  124. data/release_notes/release_4.3.9.md +14 -0
  125. data/release_notes/release_4.4.0.md +16 -0
  126. data/release_notes/release_4.5.1.md +11 -0
  127. data/release_notes/release_4.5.2.md +14 -0
  128. data/release_notes/release_4.5.3.md +29 -0
  129. data/release_notes/release_4.6.0.md +24 -0
  130. data/release_notes/release_4.6.1.md +14 -0
  131. data/release_notes/release_4.6.2.md +16 -0
  132. data/release_notes/release_4.6.3.rc1.md +14 -0
  133. data/release_notes/release_4.6.3.rc2.md +14 -0
  134. data/release_notes/release_4.6.3.rc3.md +17 -0
  135. data/release_notes/release_4.7.0.md +11 -0
  136. data/release_notes/release_4.7.1.md +14 -0
  137. data/release_notes/release_4.7.1.rc.1.md +14 -0
  138. data/release_notes/release_4.7.1.rc1.md +19 -0
  139. data/script/gpp +3 -0
  140. data/spec/cc_api_stub/app_usage_events_spec.rb +12 -0
  141. data/spec/cc_api_stub/applications_spec.rb +69 -0
  142. data/spec/cc_api_stub/domains_spec.rb +40 -0
  143. data/spec/cc_api_stub/events_spec.rb +12 -0
  144. data/spec/cc_api_stub/frameworks_spec.rb +19 -0
  145. data/spec/cc_api_stub/login_spec.rb +20 -0
  146. data/spec/cc_api_stub/organization_users_spec.rb +35 -0
  147. data/spec/cc_api_stub/organizations_spec.rb +118 -0
  148. data/spec/cc_api_stub/routes_spec.rb +19 -0
  149. data/spec/cc_api_stub/runtimes_spec.rb +19 -0
  150. data/spec/cc_api_stub/service_bindings_spec.rb +13 -0
  151. data/spec/cc_api_stub/service_instances_spec.rb +19 -0
  152. data/spec/cc_api_stub/services_spec.rb +11 -0
  153. data/spec/cc_api_stub/space_users_spec.rb +35 -0
  154. data/spec/cc_api_stub/spaces_spec.rb +38 -0
  155. data/spec/cc_api_stub/users_spec.rb +107 -0
  156. data/spec/cfoundry/auth_token_spec.rb +153 -0
  157. data/spec/cfoundry/baseclient_spec.rb +284 -0
  158. data/spec/cfoundry/client_spec.rb +13 -0
  159. data/spec/cfoundry/errors_spec.rb +117 -0
  160. data/spec/cfoundry/rest_client_spec.rb +367 -0
  161. data/spec/cfoundry/trace_helpers_spec.rb +91 -0
  162. data/spec/cfoundry/uaaclient_spec.rb +421 -0
  163. data/spec/cfoundry/upload_helpers_spec.rb +182 -0
  164. data/spec/cfoundry/v2/app_event_spec.rb +97 -0
  165. data/spec/cfoundry/v2/app_instance_spec.rb +31 -0
  166. data/spec/cfoundry/v2/app_spec.rb +354 -0
  167. data/spec/cfoundry/v2/app_usage_event_spec.rb +15 -0
  168. data/spec/cfoundry/v2/base_spec.rb +375 -0
  169. data/spec/cfoundry/v2/client_spec.rb +121 -0
  170. data/spec/cfoundry/v2/domain_spec.rb +63 -0
  171. data/spec/cfoundry/v2/event_spec.rb +15 -0
  172. data/spec/cfoundry/v2/managed_service_instance_spec.rb +149 -0
  173. data/spec/cfoundry/v2/model_magic/attribute_spec.rb +123 -0
  174. data/spec/cfoundry/v2/model_magic/has_summary_spec.rb +17 -0
  175. data/spec/cfoundry/v2/model_magic/to_many_spec.rb +53 -0
  176. data/spec/cfoundry/v2/model_magic/to_one_spec.rb +106 -0
  177. data/spec/cfoundry/v2/model_magic_spec.rb +43 -0
  178. data/spec/cfoundry/v2/model_spec.rb +472 -0
  179. data/spec/cfoundry/v2/organization_spec.rb +282 -0
  180. data/spec/cfoundry/v2/quota_definition_spec.rb +50 -0
  181. data/spec/cfoundry/v2/route_spec.rb +42 -0
  182. data/spec/cfoundry/v2/service_plan_spec.rb +53 -0
  183. data/spec/cfoundry/v2/service_spec.rb +58 -0
  184. data/spec/cfoundry/v2/space_spec.rb +160 -0
  185. data/spec/cfoundry/v2/user_provided_service_instance_spec.rb +57 -0
  186. data/spec/cfoundry/v2/user_spec.rb +206 -0
  187. data/spec/cfoundry/validator_spec.rb +94 -0
  188. data/spec/factories/app_events_factory.rb +7 -0
  189. data/spec/factories/app_usage_events_factory.rb +32 -0
  190. data/spec/factories/apps_factory.rb +11 -0
  191. data/spec/factories/clients_factory.rb +7 -0
  192. data/spec/factories/domains_factory.rb +10 -0
  193. data/spec/factories/events_factory.rb +50 -0
  194. data/spec/factories/organizations_factory.rb +12 -0
  195. data/spec/factories/quota_definitions_factory.rb +8 -0
  196. data/spec/factories/routes_factory.rb +10 -0
  197. data/spec/factories/service_instances_factory.rb +10 -0
  198. data/spec/factories/service_plans_factory.rb +10 -0
  199. data/spec/factories/services_factory.rb +10 -0
  200. data/spec/factories/spaces_factory.rb +10 -0
  201. data/spec/factories/user_provided_service_instances_factory.rb +10 -0
  202. data/spec/factories/users_factory.rb +10 -0
  203. data/spec/fixtures/apps/with_cfignore/.cfignore +4 -0
  204. data/spec/fixtures/apps/with_cfignore/.hidden_file +1 -0
  205. data/spec/fixtures/apps/with_cfignore/ambiguous_ignored +0 -0
  206. data/spec/fixtures/apps/with_cfignore/ignored_dir/file_in_ignored_dir.txt +1 -0
  207. data/spec/fixtures/apps/with_cfignore/ignored_file.txt +1 -0
  208. data/spec/fixtures/apps/with_cfignore/non_ignored_dir/file_in_non_ignored_dir.txt +1 -0
  209. data/spec/fixtures/apps/with_cfignore/non_ignored_dir/ignored_file.txt +1 -0
  210. data/spec/fixtures/apps/with_cfignore/non_ignored_dir/toplevel_ignored.txt +0 -0
  211. data/spec/fixtures/apps/with_cfignore/non_ignored_file.txt +1 -0
  212. data/spec/fixtures/apps/with_cfignore/toplevel_ignored.txt +0 -0
  213. data/spec/fixtures/apps/with_dotfiles/.dotfile +1 -0
  214. data/spec/fixtures/apps/with_dotfiles/xyz +1 -0
  215. data/spec/fixtures/apps/with_external_symlink/foo +1 -0
  216. data/spec/fixtures/apps/with_ignored_external_symlink/.cfignore +1 -0
  217. data/spec/fixtures/apps/with_ignored_external_symlink/foo +1 -0
  218. data/spec/fixtures/apps/with_nested_directories/foo/bar/baz/fizz +0 -0
  219. data/spec/fixtures/apps/with_nested_directories/xyz +0 -0
  220. data/spec/fixtures/empty_file +0 -0
  221. data/spec/fixtures/fake_cc_app_usage_events.json +152 -0
  222. data/spec/fixtures/fake_cc_application.json +20 -0
  223. data/spec/fixtures/fake_cc_application_summary.json +56 -0
  224. data/spec/fixtures/fake_cc_created_application.json +11 -0
  225. data/spec/fixtures/fake_cc_created_domain.json +15 -0
  226. data/spec/fixtures/fake_cc_created_organization.json +11 -0
  227. data/spec/fixtures/fake_cc_created_route.json +13 -0
  228. data/spec/fixtures/fake_cc_created_service_instance.json +11 -0
  229. data/spec/fixtures/fake_cc_created_space.json +11 -0
  230. data/spec/fixtures/fake_cc_created_user.json +11 -0
  231. data/spec/fixtures/fake_cc_domain.json +55 -0
  232. data/spec/fixtures/fake_cc_domain_spaces.json +27 -0
  233. data/spec/fixtures/fake_cc_empty_search.json +7 -0
  234. data/spec/fixtures/fake_cc_events.json +419 -0
  235. data/spec/fixtures/fake_cc_frameworks.json +20 -0
  236. data/spec/fixtures/fake_cc_managed_service_instance.json +83 -0
  237. data/spec/fixtures/fake_cc_organization.json +161 -0
  238. data/spec/fixtures/fake_cc_organization_domains.json +59 -0
  239. data/spec/fixtures/fake_cc_organization_search.json +37 -0
  240. data/spec/fixtures/fake_cc_organization_spaces.json +99 -0
  241. data/spec/fixtures/fake_cc_organization_summary.json +20 -0
  242. data/spec/fixtures/fake_cc_organization_users.json +81 -0
  243. data/spec/fixtures/fake_cc_route.json +16 -0
  244. data/spec/fixtures/fake_cc_runtimes.json +20 -0
  245. data/spec/fixtures/fake_cc_service_binding.json +22 -0
  246. data/spec/fixtures/fake_cc_service_bindings.json +24 -0
  247. data/spec/fixtures/fake_cc_service_instance.json +83 -0
  248. data/spec/fixtures/fake_cc_service_instances.json +72 -0
  249. data/spec/fixtures/fake_cc_services.json +160 -0
  250. data/spec/fixtures/fake_cc_space.json +45 -0
  251. data/spec/fixtures/fake_cc_space_apps.json +49 -0
  252. data/spec/fixtures/fake_cc_space_summary.json +84 -0
  253. data/spec/fixtures/fake_cc_spaces.json +92 -0
  254. data/spec/fixtures/fake_cc_stats.json +29 -0
  255. data/spec/fixtures/fake_cc_user.json +139 -0
  256. data/spec/fixtures/fake_cc_user_organizations.json +92 -0
  257. data/spec/fixtures/fake_cc_user_provided_service_instance.json +51 -0
  258. data/spec/fixtures/fake_cc_user_with_managers.json +85 -0
  259. data/spec/integration/client_spec.rb +38 -0
  260. data/spec/spec_helper.rb +22 -0
  261. data/spec/support/factory_girl.rb +6 -0
  262. data/spec/support/shared_examples/cc_api_stub_request_examples.rb +79 -0
  263. data/spec/support/shared_examples/client_login_examples.rb +46 -0
  264. data/spec/support/shared_examples/model_summary_examples.rb +34 -0
  265. data/spec/support/test_model_builder.rb +10 -0
  266. data/vendor/errors/v1.yml +189 -0
  267. data/vendor/errors/v2.yml +845 -0
  268. metadata +712 -0
@@ -0,0 +1,112 @@
1
+ require "multi_json"
2
+
3
+ require "cfoundry/baseclient"
4
+ require "cfoundry/uaaclient"
5
+
6
+ require "cfoundry/errors"
7
+
8
+ module CFoundry::V2
9
+ class Base < CFoundry::BaseClient
10
+ include BaseClientMethods
11
+
12
+ def resource_match(fingerprints)
13
+ put("v2", "resource_match", :content => :json, :accept => :json, :payload => fingerprints)
14
+ end
15
+
16
+ def upload_app(guid, zipfile = nil, resources = [])
17
+ payload = {}
18
+ payload[:resources] = MultiJson.dump(resources)
19
+
20
+ if zipfile
21
+ payload[:application] =
22
+ UploadIO.new(
23
+ if zipfile.is_a? File
24
+ zipfile
25
+ elsif zipfile.is_a? String
26
+ File.new(zipfile, "rb")
27
+ end,
28
+ "application/zip")
29
+ end
30
+
31
+ response = put("v2", "apps", guid, "bits",
32
+ :payload => payload,
33
+ :params => {"async" => "true"})
34
+
35
+ if response.present?
36
+ response_json = JSON.parse(response)
37
+ poll_upload_until_finished(response_json['metadata']['guid'])
38
+ end
39
+ rescue EOFError
40
+ retry
41
+ end
42
+
43
+ def poll_upload_until_finished(guid)
44
+ while true
45
+ response = get("v2", "jobs", guid, :accept => :json)
46
+ break if response[:entity][:status] == "finished"
47
+
48
+ if response[:entity][:status] == "failed"
49
+ raise CFoundry::BadResponse
50
+ end
51
+ sleep 0.2
52
+ end
53
+ end
54
+
55
+ def files(guid, instance, *path)
56
+ get("v2", "apps", guid, "instances", instance, "files", *path)
57
+ end
58
+
59
+ alias :file :files
60
+
61
+ def stream_file(guid, instance, *path, &blk)
62
+ path_and_options = path + [{:return_response => true, :follow_redirects => false}]
63
+ redirect = get("v2", "apps", guid, "instances", instance, "files", *path_and_options)
64
+
65
+ if location = redirect[:headers]["location"]
66
+ stream_url(location + "&tail", &blk)
67
+ else
68
+ yield redirect[:body]
69
+ end
70
+ end
71
+
72
+ def instances(guid)
73
+ get("v2", "apps", guid, "instances", :accept => :json)
74
+ end
75
+
76
+ def crashes(guid)
77
+ get("v2", "apps", guid, "crashes", :accept => :json)
78
+ end
79
+
80
+ def stats(guid)
81
+ get("v2", "apps", guid, "stats", :accept => :json)
82
+ end
83
+
84
+ def env(guid)
85
+ get("v2", "apps", guid, "env", :accept => :json)
86
+ end
87
+
88
+ def update_app(guid, diff)
89
+ put("v2", "apps", guid,
90
+ :content => :json,
91
+ :payload => diff,
92
+ :return_response => true)
93
+ end
94
+
95
+ def for_each(paginated, &block)
96
+ paginated[:resources].each &block
97
+
98
+ while (next_page = paginated[:next_url])
99
+ paginated = get(next_page, :accept => :json)
100
+ paginated[:resources].each &block
101
+ end
102
+ end
103
+
104
+ def all_pages(paginated)
105
+ payload = []
106
+ for_each(paginated) do |resource|
107
+ payload << resource
108
+ end
109
+ payload
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,104 @@
1
+ require File.expand_path("../../concerns/login_helpers", __FILE__)
2
+ require "forwardable"
3
+
4
+ module CFoundry::V2
5
+ # The primary API entrypoint. Wraps a BaseClient to provide nicer return
6
+ # values. Initialize with the target and, optionally, an auth token. These
7
+ # are the only two internal states.
8
+ class Client
9
+ include ClientMethods, CFoundry::LoginHelpers
10
+ extend Forwardable
11
+
12
+ # Internal BaseClient instance. Normally won't be touching this.
13
+ attr_reader :base
14
+
15
+ # [Organization] Currently targeted organization.
16
+ attr_accessor :current_organization
17
+
18
+ # [Space] Currently targeted space.
19
+ attr_accessor :current_space
20
+
21
+ def_delegators :@base, :target, :target=, :token, :token=,
22
+ :trace, :trace=, :log, :log=, :info
23
+
24
+ # Create a new Client for interfacing with the given target.
25
+ #
26
+ # A token may also be provided to skip the login step.
27
+ def initialize(target, token = nil, options = {})
28
+ @base = Base.new(target, token, options)
29
+ end
30
+
31
+ def version
32
+ 2
33
+ end
34
+
35
+ # The currently authenticated user.
36
+ def current_user
37
+ return unless token
38
+
39
+ token_data = @base.token.token_data
40
+ if guid = token_data[:user_id]
41
+ user = user(guid)
42
+ user.emails = [{ :value => token_data[:email] }]
43
+ user
44
+ end
45
+ end
46
+
47
+ def login(credentials)
48
+ @current_organization = nil
49
+ @current_space = nil
50
+ super
51
+ end
52
+
53
+ def register(email, password, options = {})
54
+ uaa_user = @base.uaa.add_user(email, password, options)
55
+ cc_user = user
56
+ cc_user.guid = uaa_user[:id]
57
+ cc_user.create!
58
+ cc_user
59
+ end
60
+
61
+ # Clear client token. No requests are made for this.
62
+ def logout
63
+ @base.token = nil
64
+ end
65
+
66
+ # Is an authentication token set on the client?
67
+ def logged_in?
68
+ !!@base.token
69
+ end
70
+
71
+ def query_target(klass)
72
+ if klass.scoped_space && space = current_space
73
+ space
74
+ elsif klass.scoped_organization && org = current_organization
75
+ org
76
+ else
77
+ self
78
+ end
79
+ end
80
+
81
+ def stream_url(url, &blk)
82
+ @base.stream_url(url, &blk)
83
+ end
84
+
85
+ def service_instances(opts={})
86
+ opts[:user_provided] = true
87
+ super(opts)
88
+ end
89
+
90
+ def service_instances_from(path, *args)
91
+ opts = args.first || {}
92
+ opts[:user_provided] = true
93
+ super(path, opts, *args)
94
+ end
95
+
96
+ def make_service_instance(json)
97
+ klass = "CFoundry::V2::#{json[:entity][:type].camelize}".constantize
98
+ klass.new(
99
+ json[:metadata][:guid],
100
+ self,
101
+ json)
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,20 @@
1
+ require "cfoundry/v2/model"
2
+
3
+ module CFoundry::V2
4
+ class Domain < Model
5
+ validates_presence_of :name
6
+ validates_format_of :name, :with => /\A([^\.]+\.)+[^\.]+\Z/
7
+ validates_presence_of :owning_organization
8
+
9
+ attribute :name, :string
10
+ attribute :wildcard, :boolean
11
+ to_one :owning_organization, :as => :organization, :default => nil
12
+ to_many :spaces
13
+
14
+ queryable_by :name, :owning_organization_guid, :space_guid
15
+
16
+ def system?
17
+ guid.present? && !owning_organization.present?
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ require "cfoundry/v2/model"
2
+
3
+ module CFoundry::V2
4
+ class Event < Model
5
+ attribute :actee, :string
6
+ attribute :actee_type, :string
7
+ attribute :actor, :string
8
+ attribute :actor_type, :string
9
+ attribute :organization_guid, :string
10
+ attribute :space_guid, :string
11
+ attribute :timestamp, :string
12
+ attribute :type, :string
13
+ attribute :metadata, Hash
14
+
15
+ queryable_by :type, :timestamp
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module CFoundry::V2::Helper
2
+ def to_many_support(plural)
3
+ singular = plural.to_s.sub(/s$/, "").to_sym
4
+
5
+ alias_method :"remove_#{singular}_without_support", :"remove_#{singular}"
6
+ define_method(:"remove_#{singular}") do |x|
7
+ result = self.__send__("remove_#{singular}_without_support", x)
8
+ result.nil?
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ require "cfoundry/v2/service_instance"
2
+
3
+ module CFoundry::V2
4
+ class ManagedServiceInstance < ServiceInstance
5
+ attribute :credentials, :hash
6
+ attribute :parameters, :hash
7
+ to_one :service_plan
8
+
9
+ def self.object_name
10
+ 'service_instance'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,213 @@
1
+ require "multi_json"
2
+ require "cfoundry/v2/model_magic"
3
+
4
+ module CFoundry::V2
5
+ class Model
6
+ include ActiveModel::Validations
7
+
8
+ @@objects = {}
9
+
10
+ extend ModelMagic
11
+
12
+ class << self
13
+ def objects
14
+ @@objects
15
+ end
16
+
17
+ def inherited(klass)
18
+ @@objects[klass.object_name] = klass
19
+ super
20
+ end
21
+ end
22
+
23
+ attr_accessor :guid, :cache, :changes
24
+ attr_reader :created_at, :updated_at
25
+ attr_reader :diff
26
+
27
+ def initialize(guid, client, manifest = nil, partial = false)
28
+ @guid = guid
29
+ @client = client
30
+ @manifest = manifest
31
+ @partial = partial
32
+ @cache = {}
33
+ @diff = {}
34
+ @changes = {}
35
+ end
36
+
37
+ def created_at
38
+ timestamp = @manifest.try(:[], :metadata).try(:[], :created_at)
39
+ DateTime.parse(timestamp) if timestamp.present?
40
+ end
41
+
42
+ def updated_at
43
+ timestamp = @manifest.try(:[], :metadata).try(:[], :updated_at)
44
+ DateTime.parse(timestamp) if timestamp.present?
45
+ end
46
+
47
+ def manifest
48
+ @manifest ||= @client.base.send(object_name, @guid)
49
+ end
50
+
51
+ def partial?
52
+ @partial
53
+ end
54
+
55
+ def changed?
56
+ !@changes.empty?
57
+ end
58
+
59
+ def inspect
60
+ "\#<#{self.class.name} '#@guid'>"
61
+ end
62
+
63
+ def object_name
64
+ @object_name ||= self.class.object_name
65
+ end
66
+
67
+ def plural_object_name
68
+ @plural_object_name ||= self.class.plural_object_name
69
+ end
70
+
71
+ def invalidate!
72
+ @manifest = nil
73
+ @partial = false
74
+ @cache = {}
75
+ @diff = {}
76
+ @changes = {}
77
+ end
78
+
79
+ def create(options = {})
80
+ create!(options)
81
+ true
82
+ rescue CFoundry::APIError => e
83
+ if e.instance_of? CFoundry::APIError
84
+ errors.add(:base, :cc_client)
85
+ else
86
+ errors.add(attribute_for_error(e), e.message)
87
+ end
88
+ false
89
+ end
90
+
91
+ def attribute_for_error(error)
92
+ :base
93
+ end
94
+
95
+ # this does a bit of extra processing to allow for
96
+ # `delete!' followed by `create!'
97
+ def create!(options = {})
98
+ payload = {}
99
+
100
+ @manifest ||= {}
101
+ @manifest[:entity] ||= {}
102
+
103
+ @manifest[:entity].each do |k, v|
104
+ if v.is_a?(Hash) && v.key?(:metadata)
105
+ # skip; there's a _guid attribute already
106
+ elsif v.is_a?(Array) && !v.empty? && v.all? { |x|
107
+ x.is_a?(Hash) && x.key?(:metadata)
108
+ }
109
+ singular = k.to_s.sub(/s$/, "")
110
+
111
+ payload[:"#{singular}_guids"] = v.collect do |x|
112
+ if x.is_a?(Hash) && x.key?(:metadata)
113
+ x[:metadata][:guid]
114
+ else
115
+ x
116
+ end
117
+ end
118
+ else
119
+ payload[k] = v
120
+ end
121
+ end
122
+
123
+ @manifest = @client.base.post("v2", create_endpoint_name,
124
+ :content => :json,
125
+ :accept => :json,
126
+ :payload => payload,
127
+ :params => options
128
+ )
129
+
130
+ @guid = @manifest[:metadata][:guid]
131
+
132
+ @diff.clear
133
+
134
+ true
135
+ end
136
+
137
+ def create_endpoint_name
138
+ plural_object_name
139
+ end
140
+
141
+ def update!(options ={})
142
+ @manifest = @client.base.put("v2", plural_object_name, guid,
143
+ :content => :json,
144
+ :accept => :json,
145
+ :payload => @diff,
146
+ :params => options
147
+ )
148
+
149
+ @diff.clear
150
+
151
+ true
152
+ end
153
+
154
+ def delete(options = {})
155
+ delete!(options)
156
+ rescue CFoundry::APIError => e
157
+ if e.instance_of? CFoundry::APIError
158
+ errors.add(:base, :cc_client)
159
+ else
160
+ errors.add(attribute_for_error(e), e.message)
161
+ end
162
+ false
163
+ end
164
+
165
+ def delete!(options = {})
166
+ @client.base.delete("v2", plural_object_name, guid, :params => options)
167
+
168
+ @deleted = true
169
+
170
+ @diff.clear
171
+
172
+ if @manifest
173
+ @manifest.delete :metadata
174
+ end
175
+
176
+ true
177
+ end
178
+
179
+ def to_param
180
+ persisted? ? @guid.to_s : nil
181
+ end
182
+
183
+ def to_key
184
+ persisted? ? [@guid] : nil
185
+ end
186
+
187
+ def persisted?
188
+ @guid && !@deleted
189
+ end
190
+
191
+ def exists?
192
+ invalidate!
193
+ manifest
194
+ true
195
+ rescue CFoundry::NotFound
196
+ false
197
+ end
198
+
199
+ def query_target(klass)
200
+ self
201
+ end
202
+
203
+ def eql?(other)
204
+ other.is_a?(self.class) && @guid == other.guid
205
+ end
206
+
207
+ alias :== :eql?
208
+
209
+ def hash
210
+ @guid.hash
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,49 @@
1
+ module CFoundry::V2::ModelMagic
2
+ module Attribute
3
+ def attribute(name, type, opts = {})
4
+ attributes[name] = opts
5
+ json_name = opts[:at] || name
6
+
7
+ default = opts[:default]
8
+
9
+ if has_default = opts.key?(:default)
10
+ defaults[name] = default
11
+ end
12
+
13
+ #
14
+ # def ATTRIBUTE
15
+ #
16
+ define_method(name) do
17
+ return @cache[name] if @cache.key?(name)
18
+ return nil unless persisted?
19
+
20
+ @cache[name] =
21
+ if manifest[:entity].key?(json_name)
22
+ manifest[:entity][json_name]
23
+ else
24
+ default
25
+ end
26
+ end
27
+
28
+ #
29
+ # def ATTRIBUTE=
30
+ #
31
+ define_method(:"#{name}=") do |val|
32
+ unless has_default && val == default
33
+ CFoundry::Validator.validate_type(val, type)
34
+ end
35
+
36
+ @cache[name] = val
37
+
38
+ @manifest ||= {}
39
+ @manifest[:entity] ||= {}
40
+
41
+ old = @manifest[:entity][json_name]
42
+ @changes[name] = [old, val] if old != val
43
+ @manifest[:entity][json_name] = val
44
+
45
+ @diff[json_name] = val
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,170 @@
1
+ module CFoundry
2
+ module V2
3
+ module ModelMagic
4
+ module ClientExtensions
5
+ def add_client_methods(klass)
6
+ singular = klass.object_name
7
+ plural = klass.plural_object_name
8
+
9
+ define_base_client_methods do
10
+ #
11
+ # def client.MODEL
12
+ #
13
+ define_method(singular) do |guid, *args|
14
+ get("v2", plural, guid,
15
+ :accept => :json,
16
+ :params => ModelMagic.params_from(args)
17
+ )
18
+ end
19
+
20
+ #
21
+ # def client.MODELs
22
+ #
23
+ define_method(plural) do |*args|
24
+ all_pages(
25
+ get("v2", plural,
26
+ :accept => :json,
27
+ :params => ModelMagic.params_from(args)
28
+ )
29
+ )
30
+ end
31
+
32
+ #
33
+ # def client.MODELs_first_page
34
+ #
35
+ define_method(:"#{plural}_first_page") do |*args|
36
+ get("v2", plural,
37
+ :accept => :json,
38
+ :params => ModelMagic.params_from(args)
39
+ )
40
+ end
41
+
42
+ #
43
+ # def client.MODELs_for_each
44
+ #
45
+ define_method(:"#{plural}_for_each") do |*args, &block|
46
+ for_each(get("v2", plural,
47
+ :accept => :json,
48
+ :params => ModelMagic.params_from(args)
49
+ ),
50
+ &block
51
+ )
52
+ end
53
+ end
54
+
55
+
56
+ define_client_methods do
57
+ #
58
+ # def client.MODEL
59
+ #
60
+ define_method(singular) do |*args|
61
+ guid, partial, _ = args
62
+
63
+ x = klass.new(guid, self, nil, partial)
64
+
65
+ # when creating an object, automatically set the org/space
66
+ unless guid
67
+ if klass.scoped_organization && current_organization
68
+ x.send(:"#{klass.scoped_organization}=", current_organization)
69
+ end
70
+
71
+ if klass.scoped_space && current_space
72
+ x.send(:"#{klass.scoped_space}=", current_space)
73
+ end
74
+ end
75
+
76
+ x
77
+ end
78
+
79
+ #
80
+ # def client.MODELs
81
+ #
82
+ define_method(plural) do |*args|
83
+ # use current org/space
84
+ if klass.scoped_space && current_space
85
+ current_space.send(plural, *args)
86
+ elsif klass.scoped_organization && current_organization
87
+ current_organization.send(plural, *args)
88
+ else
89
+ @base.send(plural, *args).collect do |json|
90
+ send(:"make_#{singular}", json)
91
+ end
92
+ end
93
+ end
94
+
95
+ #
96
+ # def client.MODELs_first_page
97
+ #
98
+ define_method(:"#{plural}_first_page") do |*args|
99
+ response = @base.send(:"#{plural}_first_page", *args)
100
+ results = response[:resources].collect do |json|
101
+ send(:"make_#{singular}", json)
102
+ end
103
+ {
104
+ :next_page => !!response[:next_url],
105
+ :results => results
106
+ }
107
+ end
108
+
109
+ #
110
+ # def client.MODELs_for_each
111
+ #
112
+ define_method(:"#{plural}_for_each") do |*args, &block|
113
+ @base.send(:"#{plural}_for_each", *args) do |json|
114
+ result = send(:"make_#{singular}", json)
115
+ block.call(result)
116
+ end
117
+ end
118
+
119
+ #
120
+ # def client.MODEL_from
121
+ #
122
+ define_method(:"#{singular}_from") do |path, *args|
123
+ send(
124
+ :"make_#{singular}",
125
+ @base.get(
126
+ path,
127
+ :accept => :json,
128
+ :params => ModelMagic.params_from(args)))
129
+ end
130
+
131
+ #
132
+ # def client.MODELs_from
133
+ #
134
+ define_method(:"#{plural}_from") do |path, *args|
135
+ objs = @base.all_pages(
136
+ @base.get(
137
+ path,
138
+ :accept => :json,
139
+ :params => ModelMagic.params_from(args)))
140
+
141
+ objs.collect do |json|
142
+ send(:"make_#{singular}", json)
143
+ end
144
+ end
145
+
146
+ #
147
+ # def client.make_MODEL
148
+ #
149
+ define_method(:"make_#{singular}") do |json|
150
+ klass.new(
151
+ json[:metadata][:guid],
152
+ self,
153
+ json)
154
+ end
155
+ end
156
+ end
157
+
158
+ private
159
+
160
+ def define_client_methods(&blk)
161
+ ClientMethods.module_eval(&blk)
162
+ end
163
+
164
+ def define_base_client_methods(&blk)
165
+ BaseClientMethods.module_eval(&blk)
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end