module Nucleus::Adapters::V1::CloudFoundryV2::Domains

Application domain / route functionality to support the Cloud Foundry API.

Public Instance Methods

create_domain(application_name_or_id, domain) click to toggle source

@see Stub#create_domain

# File lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb, line 29
def create_domain(application_name_or_id, domain)
  domains(application_name_or_id).each do |existing_domain|
    if existing_domain[:name] == domain[:name]
      raise Errors::SemanticAdapterRequestError,
            "Domain '#{domain[:name]}' is already assigned to the application"
    end
  end

  app_guid = app_guid(application_name_or_id)
  # extract the hostname and the domain name from the FQDN
  /(?<domain_host>([-\w]+\.)*)(?<domain_name>([-\w]+\.[-\w]+))/ =~ domain[:name]
  domain_host.chomp!('.') unless domain_host.nil?

  # finally build the response
  route_to_nucleus_domain(create_cf_domain(app_guid, domain_name, domain_host))
end
delete_domain(application_name_or_id, route_id) click to toggle source

@see Stub#delete_domain

# File lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb, line 47
def delete_domain(application_name_or_id, route_id)
  app_guid = app_guid(application_name_or_id)
  # remove route from the app
  delete_response = delete("/v2/apps/#{app_guid}/routes/#{route_id}", expects: [201, 400])
  if delete_response.status == 400
    cf_error = delete_response.body[:code]
    if cf_error == 1002
      raise Errors::AdapterResourceNotFoundError, 'Domain not found. '\
        'CF context specific: Route does not exist or is not assigned with this application'
    else
      # delete failed with 400, but not due to invalid domain
      raise Errors::AdapterRequestError,
            "#{delete_response.body[:description]} (#{cf_error} - #{delete_response.body[:error_code]})"
    end
  end

  # check route usage
  route_in_apps = get("/v2/routes/#{route_id}/apps").body
  return unless route_in_apps[:total_results] == 0

  # route is no longer needed, delete
  delete("/v2/routes/#{route_id}")
end
domain(application_name_or_id, domain_id) click to toggle source

@see Stub#domain

# File lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb, line 20
def domain(application_name_or_id, domain_id)
  app_guid = app_guid(application_name_or_id)
  assigned_routes = get("/v2/apps/#{app_guid}/routes").body
  assigned_routes[:resources].each do |assigned_route|
    return route_to_nucleus_domain(assigned_route) if assigned_route[:metadata][:guid] == domain_id
  end
end
domains(domain_id) click to toggle source

@see Stub#domains

# File lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb, line 8
def domains(domain_id)
  app_guid = app_guid(domain_id)
  assigned_routes = get("/v2/apps/#{app_guid}/routes").body
  domains = []
  assigned_routes[:resources].each do |assigned_route|
    nucleus_domain = route_to_nucleus_domain(assigned_route)
    domains.push(nucleus_domain) unless nucleus_domain[:name] == app_web_url(app_guid)
  end
  domains
end

Private Instance Methods

cf_domain(domain_name) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb, line 103
def cf_domain(domain_name)
  %w(private shared).each do |domain_type|
    response = get("/v2/#{domain_type}_domains").body
    response[:resources].each do |domain|
      return domain if domain[:entity][:name] == domain_name
    end
  end
  nil
end
cf_route(domain_guid, domain_host) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb, line 113
def cf_route(domain_guid, domain_host)
  # There is no way to check if a root domain (empty hostname) is already taken.
  # Therefore we must iterate through all routes and find matches...
  all_routes = get('/v2/routes').body[:resources]
  all_routes.each do |route|
    return route if route[:entity][:domain_guid] == domain_guid && route[:entity][:host] == domain_host
  end
  nil
end
create_cf_domain(app_guid, domain_name, domain_host) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb, line 123
def create_cf_domain(app_guid, domain_name, domain_host)
  created_domain = cf_domain(domain_name)
  unless created_domain
    # domain does not exist, create!
    domain_request_body = { name: domain_name, owning_organization_guid: default_organization_guid }
    created_domain = post('/v2/private_domains', body: domain_request_body).body
  end

  created_route = cf_route(created_domain[:metadata][:guid], domain_host)
  unless created_route
    # route does not exist, create!
    route_request_body = { domain_guid: created_domain[:metadata][:guid],
                           host: domain_host, space_guid: user_space_guid }
    created_route = post('/v2/routes', body: route_request_body).body
  end

  # assign the route to the application
  put("/v2/apps/#{app_guid}/routes/#{created_route[:metadata][:guid]}").body

  # return the actual route, not the association response
  created_route
end
domain?(application_name_or_id, domain_name) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb, line 73
def domain?(application_name_or_id, domain_name)
  app_guid = app_guid(application_name_or_id)
  domain_without_protocol = %r{([a-zA-Z]+://)?([-\.\w]*)}.match(domain_name)[2]
  assigned_routes = get("/v2/apps/#{app_guid}/routes").body
  assigned_routes[:resources].each do |route|
    route_domain = get(route[:entity][:domain_url]).body
    return true if "#{route[:entity][:host]}.#{route_domain[:entity][:name]}" == domain_without_protocol
  end
  false
end
route_to_nucleus_domain(route_resource) click to toggle source
# File lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb, line 84
def route_to_nucleus_domain(route_resource)
  route_entity = route_resource[:entity]
  route_metadata = route_resource[:metadata]
  assigned_domain = get(route_entity[:domain_url]).body
  domain = { id: route_metadata[:guid], created_at: route_metadata[:created_at] }
  domain[:updated_at] = if route_metadata[:updated_at].to_s == ''
                          route_metadata[:created_at]
                        else
                          route_metadata[:updated_at]
                        end

  domain[:name] = if route_entity[:host].to_s == ''
                    assigned_domain[:entity][:name]
                  else
                    "#{route_entity[:host]}.#{assigned_domain[:entity][:name]}"
                  end
  domain
end