cloudfoundry-client 0.1.0

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 (76) hide show
  1. data/.gitignore +12 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +12 -0
  4. data/.yardopts +9 -0
  5. data/CHANGELOG.md +6 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +20 -0
  8. data/README.md +122 -0
  9. data/Rakefile +28 -0
  10. data/cloudfoundry.gemspec +29 -0
  11. data/lib/cloudfoundry.rb +34 -0
  12. data/lib/cloudfoundry/client.rb +93 -0
  13. data/lib/cloudfoundry/client/apps.rb +192 -0
  14. data/lib/cloudfoundry/client/info.rb +29 -0
  15. data/lib/cloudfoundry/client/request.rb +89 -0
  16. data/lib/cloudfoundry/client/resources.rb +16 -0
  17. data/lib/cloudfoundry/client/response.rb +68 -0
  18. data/lib/cloudfoundry/client/services.rb +122 -0
  19. data/lib/cloudfoundry/client/users.rb +121 -0
  20. data/lib/cloudfoundry/constants.rb +30 -0
  21. data/lib/cloudfoundry/exception.rb +24 -0
  22. data/lib/cloudfoundry/version.rb +27 -0
  23. data/spec/client/apps_spec.rb +423 -0
  24. data/spec/client/info_spec.rb +92 -0
  25. data/spec/client/resources_spec.rb +52 -0
  26. data/spec/client/services_spec.rb +230 -0
  27. data/spec/client/users_spec.rb +367 -0
  28. data/spec/client_spec.rb +110 -0
  29. data/spec/cloudfoundry_spec.rb +62 -0
  30. data/spec/fixtures/admin_logged/client.yml +85 -0
  31. data/spec/fixtures/admin_logged/users.yml +363 -0
  32. data/spec/fixtures/admin_logged/users_create_action.yml +36 -0
  33. data/spec/fixtures/admin_logged/users_proxy_action.yml +46 -0
  34. data/spec/fixtures/admin_logged/users_proxy_nouser_action.yml +44 -0
  35. data/spec/fixtures/admin_logged/users_unproxy_action.yml +44 -0
  36. data/spec/fixtures/app.js +16 -0
  37. data/spec/fixtures/app.zip +0 -0
  38. data/spec/fixtures/client.yml +151 -0
  39. data/spec/fixtures/client_invalid.yml +85 -0
  40. data/spec/fixtures/cloudfoundry.yml +124 -0
  41. data/spec/fixtures/cloudfoundry_vs_client.yml +159 -0
  42. data/spec/fixtures/no_logged/apps.yml +42 -0
  43. data/spec/fixtures/no_logged/client.yml +42 -0
  44. data/spec/fixtures/no_logged/info.yml +81 -0
  45. data/spec/fixtures/no_logged/resources.yml +42 -0
  46. data/spec/fixtures/no_logged/services.yml +42 -0
  47. data/spec/fixtures/no_logged/users.yml +108 -0
  48. data/spec/fixtures/no_logged/users_login_action.yml +81 -0
  49. data/spec/fixtures/no_logged/users_proxy_action.yml +42 -0
  50. data/spec/fixtures/no_logged/users_unproxy_action.yml +42 -0
  51. data/spec/fixtures/user_logged/apps.yml +828 -0
  52. data/spec/fixtures/user_logged/apps_create_action.yml +42 -0
  53. data/spec/fixtures/user_logged/apps_directory_action.yml +48 -0
  54. data/spec/fixtures/user_logged/apps_download_action.yml +55 -0
  55. data/spec/fixtures/user_logged/apps_file_action.yml +54 -0
  56. data/spec/fixtures/user_logged/apps_start_action.yml +81 -0
  57. data/spec/fixtures/user_logged/apps_stats_action.yml +44 -0
  58. data/spec/fixtures/user_logged/apps_update_info_action.yml +44 -0
  59. data/spec/fixtures/user_logged/apps_upload_filename_action.yml +62 -0
  60. data/spec/fixtures/user_logged/apps_upload_zipfile_action.yml +62 -0
  61. data/spec/fixtures/user_logged/client.yml +85 -0
  62. data/spec/fixtures/user_logged/info.yml +126 -0
  63. data/spec/fixtures/user_logged/resources.yml +44 -0
  64. data/spec/fixtures/user_logged/resources_check_action.yml +42 -0
  65. data/spec/fixtures/user_logged/services.yml +354 -0
  66. data/spec/fixtures/user_logged/services_bind_action.yml +161 -0
  67. data/spec/fixtures/user_logged/services_create_action.yml +83 -0
  68. data/spec/fixtures/user_logged/services_unbind_action.yml +122 -0
  69. data/spec/fixtures/user_logged/services_unbind_fail_action.yml +122 -0
  70. data/spec/fixtures/user_logged/users.yml +299 -0
  71. data/spec/fixtures/user_logged/users_proxy_action.yml +44 -0
  72. data/spec/fixtures/user_logged/users_unproxy_action.yml +44 -0
  73. data/spec/spec_helper.rb +29 -0
  74. data/spec/support/cf_connection_helper.rb +26 -0
  75. data/spec/support/vcr.rb +8 -0
  76. metadata +235 -0
@@ -0,0 +1,29 @@
1
+ module CloudFoundry
2
+ class Client
3
+ # CloudFoundry API Info methods.
4
+ module Info
5
+ # Returns information about the target cloud and, if logged, information about the user account.
6
+ #
7
+ # @return [Hash] Information about the target cloud and, if logged, information about the user account.
8
+ def cloud_info()
9
+ get(CloudFoundry::Client::CLOUD_INFO_PATH)
10
+ end
11
+
12
+ # Returns information about system runtimes that are available on the target cloud.
13
+ #
14
+ # @return [Hash] System Runtimes available on the target cloud.
15
+ def cloud_runtimes_info()
16
+ get(CloudFoundry::Client::CLOUD_RUNTIMES_INFO_PATH)
17
+ end
18
+
19
+ # Returns information about system services that are available on the target cloud.
20
+ #
21
+ # @return [Hash] System Services available on the target cloud.
22
+ # @authenticated True
23
+ def cloud_services_info()
24
+ require_login
25
+ get(CloudFoundry::Client::CLOUD_SERVICES_INFO_PATH)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,89 @@
1
+ module CloudFoundry
2
+ class Client
3
+ # CloudFoundry API Request Methods.
4
+ module Request
5
+
6
+ # Performs an HTTP GET request to the target cloud.
7
+ #
8
+ # @param [String] path Path to request at target cloud.
9
+ # @param [Hash] options
10
+ # @option options [Boolean] :raw true if response must not be parsed.
11
+ def get(path, options = {})
12
+ request(:get, path, options)
13
+ end
14
+
15
+ # Performs an HTTP POST request to the target cloud.
16
+ #
17
+ # @param [String] path Path to request at target cloud.
18
+ # @param [Hash] body Body of the request to the target cloud.
19
+ # @param [Hash] options
20
+ # @option options [Boolean] :raw true if response must not be parsed.
21
+ def post(path, body = {}, options = {})
22
+ request(:post, path, options, body)
23
+ end
24
+
25
+ # Performs an HTTP PUT request to the target cloud.
26
+ #
27
+ # @param [String] path Path to request at target cloud.
28
+ # @param [Hash] body Body of the request to the target cloud.
29
+ # @param [Hash] options
30
+ # @option options [Boolean] :raw true if response must not be parsed.
31
+ def put(path, body = {}, options = {})
32
+ request(:put, path, options, body)
33
+ end
34
+
35
+ # Performs an HTTP DELETE request to the target cloud.
36
+ #
37
+ # @param [String] path Path to request at target cloud.
38
+ # @param [Hash] options
39
+ # @option options [Boolean] :raw true if response must not be parsed.
40
+ def delete(path, options = {})
41
+ request(:delete, path, options)
42
+ end
43
+
44
+ private
45
+
46
+ # Sets a new connection to target cloud.
47
+ #
48
+ # @param [Hash] options
49
+ # @option options [Boolean] :raw true if response must not be parsed.
50
+ # @return [Faraday::Connection] A Faraday Connection.
51
+ def connection(options = {})
52
+ connection_options = {
53
+ :proxy => @proxy_url,
54
+ :url => @target_url
55
+ }
56
+ connection = Faraday.new(connection_options) do |builder|
57
+ builder.use Faraday::Request::Multipart
58
+ builder.use Faraday::Request::UrlEncoded
59
+ builder.use Faraday::Request::JSON unless options[:raw]
60
+ builder.adapter @net_adapter
61
+ builder.use CloudFoundry::Client::Response::ParseJSON unless options[:raw]
62
+ builder.use CloudFoundry::Client::Response::CloudError
63
+ end
64
+ end
65
+
66
+ # Performs a request to the target cloud.
67
+ #
68
+ # @param [Symbol] method HTTP method to use.
69
+ # @param [String] path Path to request at target cloud.
70
+ # @param [Hash] options
71
+ # @param [Hash] payload Body of the request to the target cloud.
72
+ # @option options [Boolean] :raw true if response must not be parsed.
73
+ def request(method, path, options = {}, payload = nil)
74
+ headers = {}
75
+ headers["User-Agent"] = "cloudfoundry-client-" + CloudFoundry::Client::VERSION
76
+ headers["AUTHORIZATION"] = @auth_token if @auth_token
77
+ headers["PROXY-USER"] = @proxy_user if @proxy_user
78
+ headers["X-VCAP-Trace"] = @trace_key if @trace_key
79
+ headers["Accept"] = "application/json" unless options[:raw]
80
+ headers["Content-Type"] = "application/json" unless options[:raw]
81
+ response = connection(options).send(method, path) do |request|
82
+ request.headers = headers
83
+ request.body = payload unless payload && payload.empty?
84
+ end
85
+ options[:raw] ? response : response.body
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,16 @@
1
+ module CloudFoundry
2
+ class Client
3
+ # CloudFoundry API Resources methods.
4
+ module Resources
5
+ # Checks which resources are needed to send to the target cloud when uploading application bits.
6
+ #
7
+ # @param [Array] resources A resources manifest.
8
+ # @return [Array] A resources manifest.
9
+ # @authenticated True
10
+ def check_resources(resources)
11
+ require_login
12
+ post(CloudFoundry::Client::RESOURCES_PATH, resources)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,68 @@
1
+ module CloudFoundry
2
+ class Client
3
+ # CloudFoundry Faraday Response Middleware.
4
+ module Response
5
+ # Faraday Response Middleware to parse cloud JSON responses.
6
+ class ParseJSON < Faraday::Response::Middleware
7
+ # Parses a JSON response.
8
+ #
9
+ # @param [String] body HTTP body response.
10
+ # @return [Hash] Parsed body response with symbolized names (keys).
11
+ # @raise [CloudFoundry::Client::Exception::BadResponse] when body can not be parsed.
12
+ def parse(body)
13
+ case body
14
+ when " " then nil
15
+ else JSON.parse(body, :symbolize_names => true)
16
+ end
17
+ rescue JSON::ParserError
18
+ raise CloudFoundry::Client::Exception::BadResponse, "Can't parse response into JSON:" + body
19
+ end
20
+ end
21
+
22
+ # Faraday Response Middleware to parse cloud errors.
23
+ class CloudError < Faraday::Response::Middleware
24
+ # Checks if an error is returned by target cloud.
25
+ #
26
+ # @param [Hash] env Faraday environment.
27
+ # @raise [CloudFoundry::Client::Exception::BadRequest] when HTTP status is 400.
28
+ # @raise [CloudFoundry::Client::Exception::Forbidden] when HTTP status is 403.
29
+ # @raise [CloudFoundry::Client::Exception::NotFound] when HTTP status is 404.
30
+ # @raise [CloudFoundry::Client::Exception::ServerError] when HTTP status is 500.
31
+ # @raise [CloudFoundry::Client::Exception::BadGateway] when HTTP status is 502.
32
+ def on_complete(env)
33
+ if env[:status].to_i >= 400
34
+ err = case env[:status].to_i
35
+ when 400 then CloudFoundry::Client::Exception::BadRequest
36
+ when 403 then CloudFoundry::Client::Exception::Forbidden
37
+ when 404 then CloudFoundry::Client::Exception::NotFound
38
+ when 500 then CloudFoundry::Client::Exception::ServerError
39
+ when 502 then CloudFoundry::Client::Exception::BadGateway
40
+ end
41
+ raise err, parse_cloud_error_message(env[:status], env[:body])
42
+ end
43
+ end
44
+
45
+ # Parses a CloudFoundry error message.
46
+ #
47
+ # @param [String] status Faraday HTTP response status.
48
+ # @param [String] body Faraday HTTP response body.
49
+ # @return [String] CloudFoundry error message.
50
+ def parse_cloud_error_message(status, body)
51
+ parsed_body = JSON.parse(body, :symbolize_names => true)
52
+ if parsed_body && parsed_body[:code] && parsed_body[:description]
53
+ description = parsed_body[:description].gsub("\"","'")
54
+ "Error #{parsed_body[:code]}: #{description}"
55
+ else
56
+ "Error (HTTP #{status}): #{body}"
57
+ end
58
+ rescue JSON::ParserError
59
+ if body.nil? || body.empty?
60
+ "Error (#{status}): No Response Received"
61
+ else
62
+ "Error (JSON #{status}): #{body}"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,122 @@
1
+ module CloudFoundry
2
+ class Client
3
+ # CloudFoundry API Provisioned Services methods.
4
+ module Services
5
+ # Returns a list of provisioned services that are available on the target cloud.
6
+ #
7
+ # @return [Hash] List of provisioned services available on the target cloud.
8
+ # @authenticated True
9
+ def list_services
10
+ require_login
11
+ get(CloudFoundry::Client::SERVICES_PATH)
12
+ end
13
+
14
+ # Returns information about a provisioned service on the target cloud.
15
+ #
16
+ # @param [String] name The provisioned service name.
17
+ # @return [Hash] Provisioned service information on the target cloud.
18
+ # @raise [CloudFoundry::Client::Exception::BadParams] when provisioned service name is blank.
19
+ # @authenticated True
20
+ def service_info(name)
21
+ require_login
22
+ raise CloudFoundry::Client::Exception::BadParams, "Name cannot be blank" if name.nil? || name.empty?
23
+ get("#{CloudFoundry::Client::SERVICES_PATH}/#{name}")
24
+ end
25
+
26
+ # Creates a new provisioned service on the target cloud.
27
+ #
28
+ # @param [String] service The system service to provision.
29
+ # @param [String] name The provisioned service name.
30
+ # @return [Boolean] Returns true if provisioned service is created.
31
+ # @raise [CloudFoundry::Client::Exception::BadParams] when system service is blank.
32
+ # @raise [CloudFoundry::Client::Exception::BadParams] when system service is not a valid service at target cloud.
33
+ # @raise [CloudFoundry::Client::Exception::BadParams] when provisioned service name is blank.
34
+ # @authenticated True
35
+ def create_service(service, name)
36
+ require_login
37
+ raise CloudFoundry::Client::Exception::BadParams, "Service cannot be blank" if service.nil? || service.empty?
38
+ raise CloudFoundry::Client::Exception::BadParams, "Name cannot be blank" if name.nil? || name.empty?
39
+ service_hash = nil
40
+ services = cloud_services_info() || []
41
+ services.each do |service_type, service_value|
42
+ service_value.each do |vendor, vendor_value|
43
+ vendor_value.each do |version, service_info|
44
+ if service == service_info[:vendor]
45
+ service_hash = {
46
+ :type => service_info[:type],
47
+ :vendor => vendor,
48
+ :version => version,
49
+ :tier => "free"
50
+ }
51
+ break
52
+ end
53
+ end
54
+ end
55
+ end
56
+ raise CloudFoundry::Client::Exception::BadParams, "Service [#{service}] is not a valid service" unless service_hash
57
+ service_hash[:name] = name
58
+ post(CloudFoundry::Client::SERVICES_PATH, service_hash)
59
+ true
60
+ end
61
+
62
+ # Deletes a provisioned service on the target cloud.
63
+ #
64
+ # @param [String] name The provisioned service name.
65
+ # @return [Boolean] Returns true if provisioned service is deleted.
66
+ # @raise [CloudFoundry::Client::Exception::BadParams] when provisioned service name is blank.
67
+ # @authenticated True
68
+ def delete_service(name)
69
+ require_login
70
+ raise CloudFoundry::Client::Exception::BadParams, "Name cannot be blank" if name.nil? || name.empty?
71
+ delete("#{CloudFoundry::Client::SERVICES_PATH}/#{name}", :raw => true)
72
+ true
73
+ end
74
+
75
+ # Binds a provisioned service to an application on the target cloud.
76
+ #
77
+ # @param [String] name The provisioned service name.
78
+ # @param [String] appname The application name.
79
+ # @return [Boolean] Returns true if provisioned service is binded to application.
80
+ # @raise [CloudFoundry::Client::Exception::BadParams] when provisioned service name is blank.
81
+ # @raise [CloudFoundry::Client::Exception::BadParams] when provisioned service is already binded to application.
82
+ # @raise [CloudFoundry::Client::Exception::BadParams] when application name is blank.
83
+ # @authenticated True
84
+ def bind_service(name, appname)
85
+ require_login
86
+ raise CloudFoundry::Client::Exception::BadParams, "Service Name cannot be blank" if name.nil? || name.empty?
87
+ raise CloudFoundry::Client::Exception::BadParams, "Application Name cannot be blank" if appname.nil? || appname.empty?
88
+ service = service_info(name)
89
+ app = app_info(appname)
90
+ services = app[:services] || []
91
+ service_exists = services.index(name)
92
+ raise CloudFoundry::Client::Exception::BadParams, "Service [#{name}] is already binded to [#{appname}]" if service_exists
93
+ app[:services] = services << name
94
+ update_app(appname, app)
95
+ true
96
+ end
97
+
98
+ # Unbinds a provisioned service from an application on the target cloud.
99
+ #
100
+ # @param [String] name The provisioned service name.
101
+ # @param [String] appname The application name.
102
+ # @return [Boolean] Returns true if provisioned service is unbinded from application.
103
+ # @raise [CloudFoundry::Client::Exception::BadParams] when provisioned service name is blank.
104
+ # @raise [CloudFoundry::Client::Exception::BadParams] when provisioned service is not binded to application.
105
+ # @raise [CloudFoundry::Client::Exception::BadParams] when application name is blank.
106
+ # @authenticated True
107
+ def unbind_service(name, appname)
108
+ require_login
109
+ raise CloudFoundry::Client::Exception::BadParams, "Service Name cannot be blank" if name.nil? || name.empty?
110
+ raise CloudFoundry::Client::Exception::BadParams, "Application Name cannot be blank" if appname.nil? || appname.empty?
111
+ service = service_info(name)
112
+ app = app_info(appname)
113
+ services = app[:services] || []
114
+ service_deleted = services.delete(name)
115
+ raise CloudFoundry::Client::Exception::BadParams, "Service [#{name}] is not binded to [#{name}]" unless service_deleted
116
+ app[:services] = services
117
+ update_app(appname, app)
118
+ true
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,121 @@
1
+ module CloudFoundry
2
+ class Client
3
+ # CloudFoundry API Users methods.
4
+ module Users
5
+ # Logs the user in and returns the auth_token provided by the target cloud.
6
+ #
7
+ # @param [String] email The user's email.
8
+ # @param [String] password The user's password.
9
+ # @return [String] CloudFoundry API Authorization Token.
10
+ # @raise [CloudFoundry::Client::Exception::BadParams] when email is blank.
11
+ # @raise [CloudFoundry::Client::Exception::BadParams] when password is blank.
12
+ # @raise [CloudFoundry::Client::Exception::Forbidden] when login fails.
13
+ def login(email, password)
14
+ raise CloudFoundry::Client::Exception::BadParams, "Email cannot be blank" if email.nil? || email.empty?
15
+ raise CloudFoundry::Client::Exception::BadParams, "Password cannot be blank" if password.nil? || password.empty?
16
+ response_info = post("#{CloudFoundry::Client::USERS_PATH}/#{email}/tokens", {:password => password})
17
+ raise CloudFoundry::Client::Exception::Forbidden, "Login failed" unless response_info && response_info[:token]
18
+ @user = email
19
+ @proxy_user = nil
20
+ @auth_token = response_info[:token]
21
+ end
22
+
23
+ # Checks if the user is logged in at the cloud target.
24
+ #
25
+ # @return [Boolean] Returns true if user is logged in, false otherwise.
26
+ def logged_in?
27
+ return false unless cloud_info = cloud_info()
28
+ return false unless cloud_info[:user]
29
+ return false unless cloud_info[:usage]
30
+ @user = cloud_info[:user]
31
+ true
32
+ end
33
+
34
+ # Sets a user proxied access
35
+ #
36
+ # @param [String] email The user's email to be proxied.
37
+ # @return [String] Proxied user.
38
+ # @raise [CloudFoundry::Client::Exception::BadParams] when email is blank.
39
+ # @admin True
40
+ def set_proxy_user(email)
41
+ raise CloudFoundry::Client::Exception::BadParams, "Email cannot be blank" if email.nil? || email.empty?
42
+ @proxy_user = email
43
+ end
44
+
45
+ # Unsets a user proxied access
46
+ #
47
+ # @return [nil]
48
+ def unset_proxy_user()
49
+ @proxy_user = nil
50
+ end
51
+
52
+ # Returns the list of users on the target cloud.
53
+ #
54
+ # @return [Hash] List of users on the target cloud.
55
+ # @admin True
56
+ def list_users()
57
+ require_login
58
+ get(CloudFoundry::Client::USERS_PATH)
59
+ end
60
+
61
+ # Returns information about a user on the target cloud.
62
+ #
63
+ # @param [String] email The user's email.
64
+ # @return [Hash] User information on the target cloud.
65
+ # @raise [CloudFoundry::Client::Exception::BadParams] when email is blank.
66
+ # @authenticated True
67
+ # @admin Only when retrieving information about others users.
68
+ def user_info(email)
69
+ require_login
70
+ raise CloudFoundry::Client::Exception::BadParams, "Email cannot be blank" if email.nil? || email.empty?
71
+ get("#{CloudFoundry::Client::USERS_PATH}/#{email}")
72
+ end
73
+
74
+ # Creates a new user on the target cloud.
75
+ #
76
+ # @param [String] email The user's email.
77
+ # @param [String] password The user's password.
78
+ # @return [Boolean] Returns true if user is created.
79
+ # @raise [CloudFoundry::Client::Exception::BadParams] when email is blank.
80
+ # @raise [CloudFoundry::Client::Exception::BadParams] when password is blank.
81
+ def create_user(email, password)
82
+ raise CloudFoundry::Client::Exception::BadParams, "Email cannot be blank" if email.nil? || email.empty?
83
+ raise CloudFoundry::Client::Exception::BadParams, "Password cannot be blank" if password.nil? || password.empty?
84
+ post(CloudFoundry::Client::USERS_PATH, {:email => email, :password => password})
85
+ true
86
+ end
87
+
88
+ # Updates the user's password on the target cloud.
89
+ #
90
+ # @param [String] email The user's email.
91
+ # @param [String] password The user's password.
92
+ # @return [Boolean] Returns true if user is updated.
93
+ # @raise [CloudFoundry::Client::Exception::BadParams] when email is blank.
94
+ # @raise [CloudFoundry::Client::Exception::BadParams] when password is blank.
95
+ # @authenticated True
96
+ # @admin Only when updating password for others users.
97
+ def update_user(email, password)
98
+ require_login
99
+ raise CloudFoundry::Client::Exception::BadParams, "Email cannot be blank" if email.nil? || email.empty?
100
+ raise CloudFoundry::Client::Exception::BadParams, "Password cannot be blank" if password.nil? || password.empty?
101
+ user_info = user_info(email)
102
+ user_info[:password] = password
103
+ put("#{CloudFoundry::Client::USERS_PATH}/#{email}", user_info)
104
+ true
105
+ end
106
+
107
+ # Deletes a user on the target cloud.
108
+ #
109
+ # @param [String] email The user's email.
110
+ # @return [Boolean] Returns true if user is deleted.
111
+ # @raise [CloudFoundry::Client::Exception::BadParams] when email is blank.
112
+ # @admin True
113
+ def delete_user(email)
114
+ require_login
115
+ raise CloudFoundry::Client::Exception::BadParams, "Email cannot be blank" if email.nil? || email.empty?
116
+ delete("#{CloudFoundry::Client::USERS_PATH}/#{email}", :raw => true)
117
+ true
118
+ end
119
+ end
120
+ end
121
+ end