class Nucleus::Adapters::V1::CloudFoundryV2

The {CloudFoundryV2} adapter is designed to support the Cloud Foundry API and uses only commands of the API version 2.

Besides native Cloud Foundry installations, this adapter shall also work with forks, such as Stackato 3.4.2.

The Nucleus API is fully supported, there are no known issues. @see apidocs.cloudfoundry.org The latest Cloud Foundry API documentation

Public Class Methods

new(endpoint_url, endpoint_app_domain = nil, check_certificates = true) click to toggle source
Calls superclass method
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 27
def initialize(endpoint_url, endpoint_app_domain = nil, check_certificates = true)
  super(endpoint_url, endpoint_app_domain, check_certificates)
end

Public Instance Methods

handle_error(error) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 31
def handle_error(error)
  cf_error = error.body.is_a?(Hash) ? error.body[:code] : nil
  case error.status
  when 400
    handle_400_error(error, cf_error)
  when 404
    raise Errors::AdapterResourceNotFoundError, error.body[:description] if cf_error > 10_000
  else
    if [1001].include? cf_error
      raise Errors::AdapterRequestError, "#{error.body[:description]} (#{cf_error} - #{error.body[:error_code]})"
    elsif [10_002].include?(cf_error) || error.status == 401
      raise Errors::EndpointAuthenticationError, 'Endpoint authentication failed with OAuth2 token'
    end
  end
  # error still unhandled, will result in a 500, server error
  log.warn "Cloud Foundry error still unhandled: #{error}"
end

Private Instance Methods

app_guid(app_name_or_id) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 70
def app_guid(app_name_or_id)
  # app name is a UUID and therefore most likely the CF GUID
  return app_name_or_id if guid?(app_name_or_id)
  find_app_guid_by_name(app_name_or_id)
end
app_web_url(app_guid) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 135
def app_web_url(app_guid)
  "#{app_guid}.#{@endpoint_app_domain}" if @endpoint_app_domain
end
default_organization_guid() click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 66
def default_organization_guid
  get("/v2/spaces/#{user_space_guid}").body[:entity][:organization_guid]
end
deployed?(application_guid) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 128
def deployed?(application_guid)
  response = head("/v2/apps/#{application_guid}/download", follow_redirects: false, expects: [200, 302, 404])
  return true if response.status == 200 || response.status == 302
  return false if response.status == 404
  # if the response is neither one of the codes, the call fails anyway...
end
endpoint_info() click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 95
def endpoint_info
  get('/v2/info', headers: {}).body
end
find_app_guid_by_name(application_name) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 76
def find_app_guid_by_name(application_name)
  filtered_list_response = get('/v2/apps', query: { q: "name:#{application_name}" })
  if filtered_list_response.body[:resources].empty?
    raise Errors::AdapterResourceNotFoundError,
          "Couldn't find app with name '#{application_name}' on the platform"
  end
  # return the found guid
  filtered_list_response.body[:resources][0][:metadata][:guid]
end
find_app_id_by_name(application_name, previous_response) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 86
def find_app_id_by_name(application_name, previous_response)
  filtered_list_response = get('/v2/apps', query: { q: "name:#{application_name}" })
  # fail as expected if the app can also not be found by its name
  raise Errors::AdapterResourceNotFoundError,
        previous_response.body[:description] if filtered_list_response.body[:resources].empty?
  # return the found guid
  filtered_list_response.body[:resources][0][:metadata][:guid]
end
guid?(name_or_id) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 62
def guid?(name_or_id)
  Regexp::UUID_PATTERN.match(name_or_id) ? true : false
end
handle_400_error(error, cf_error) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 51
def handle_400_error(error, cf_error)
  if cf_error == 150_001 || cf_error == 160_001 || cf_error > 100_000 && cf_error < 109_999
    # Indicating semantically invalid parameters
    raise Errors::SemanticAdapterRequestError, error.body[:description]
  elsif cf_error == 170_002
    fail_with(:build_in_progress)
  elsif cf_error == 60_002
    raise Errors::SemanticAdapterRequestError, 'Service is already assigned to the application'
  end
end
headers() click to toggle source
Calls superclass method
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 124
def headers
  super.merge('Basic' => 'Y2Y6', 'Content-Type' => 'application/json')
end
user() click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 103
def user
  get("/v2/users/#{user_info[:user_id]}").body
end
user_info() click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 99
def user_info
  get("#{endpoint_info[:authorization_endpoint]}/userinfo").body
end
user_space_guid() click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb, line 107
def user_space_guid
  users_spaces = get('/v2/spaces').body[:resources]
  # only once space accessible
  return users_spaces[0][:metadata][:guid] if users_spaces.length == 1
  # use default space (stackato feature)
  default_space = users_spaces.detect { |space_resource| space_resource[:entity][:is_default] == true }
  return default_space[:metadata][:guid] if default_space
  # check the users spaces for default
  user_default_space_guid = user[:entity][:default_space_guid]
  return user_default_space_guid if user_default_space_guid
  # TODO: find a more suitable approach to detect the right space !?
  # multiple spaces and no default space (dammit), choose the first one...
  return users_spaces[0][:metadata][:guid] if users_spaces
  # user has no space assigned, fail since we cant determine a space guid
  fail_with(:no_space_assigned)
end