class Opsmgr::Api::HttpClient

Attributes

endpoints[R]
environment[R]
uri[R]

Public Class Methods

build(environment, om_version) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 20
def self.build(environment, om_version)
  new(environment, Opsmgr::Api::Version20::Endpoints.new, om_version)
end
new(environment, endpoints, om_version) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 24
def initialize(environment, endpoints, om_version)
  @environment = environment
  @uri = URI.parse(environment.settings.dig('ops_manager', 'url'))
  @endpoints = endpoints
  @om_version = om_version
end

Public Instance Methods

add_product(product_name, version) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 96
def add_product(product_name, version)
  req = Net::HTTP::Post.new(endpoints.add_product_path)
  req.set_form_data('name' => product_name, 'product_version' => version)
  add_auth_header(req)

  http.request(req)
end
auth_redirect_location() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 335
def auth_redirect_location
  host = environment.settings.dig('ops_manager', 'url')

  host.concat('/') unless host.end_with? '/'

  host+'auth/cloudfoundry'
end
create_env_admin_user(token) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 290
def create_env_admin_user(token)
  request = Net::HTTP::Post.new(
    endpoints.uaa_create_user
  )
  request['Content-Type'] = 'application/json'
  request['Authorization'] = token
  request.body = {
    userName: web_auth_user,
    password: web_auth_password,
    emails: [
      { value: web_auth_user }
    ]
  }.to_json

  response = http.request(request)

  if response.code != '201'
    raise("Unexpected response from UAA: code #{response.code}, body: #{response.body}")
  end
end
create_the_first_user() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 161
def create_the_first_user
  if Gem::Version.new(@om_version) >= Gem::Version.new('1.6')
    req = Net::HTTP::Post.new(endpoints.api_setup_path)
    req.set_form_data(
      'setup[user_name]' => web_auth_user,
      'setup[password]' => web_auth_password,
      'setup[password_confirmation]' => web_auth_password,
      'setup[eula_accepted]' => true
    )
  else
    req = Net::HTTP::Post.new(endpoints.api_user_path)
    req.set_form_data(
      'user[user_name]' => web_auth_user,
      'user[password]' => web_auth_password,
      'user[password_confirmation]' => web_auth_password,
    )
  end

  http.request(req)
end
delete_unused_products() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 197
def delete_unused_products
  req = Net::HTTP::Delete.new(endpoints.list_products_path)
  add_auth_header(req)

  http.request(req)
end
download_staged_manifest(product_guid) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 112
def download_staged_manifest(product_guid)
  req = Net::HTTP::Get.new(endpoints.download_staged_manifest(product_guid))
  add_auth_header(req)

  http.request(req)
end
ensure_env_admin_user_exists() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 263
def ensure_env_admin_user_exists
  token = get_oauth_token('admin')

  create_env_admin_user(token) unless verify_if_env_admin_user_exists?(token)
end
import_installation(installation_file, password) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 208
def import_installation(installation_file, password)
  create_the_first_user unless Gem::Version.new(@om_version) >= Gem::Version.new('1.7')

  log.info('uploading the installation file')
  req = Net::HTTP::Post::Multipart.new(
    endpoints.import_installation_path,
    'installation[file]' =>
      UploadIO.new(
        installation_file,
        'application/octet-stream',
        File.basename(installation_file)
      ),
    import_secret_parameter_name => password
  )

  # The post-1.7 import happens before a user has been created so we cannot authenticate.
  add_auth_header(req) unless Gem::Version.new(@om_version) >= Gem::Version.new('1.7')

  response = http.request(req)

  if Gem::Version.new(@om_version) == Gem::Version.new('1.7')
    wait_for_uaa_to_be_available

    ensure_env_admin_user_exists
  end

  response
end
import_secret_parameter_name() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 311
def import_secret_parameter_name
  Gem::Version.new(@om_version) >= Gem::Version.new('1.7') ? 'passphrase' : 'password'
end
import_stemcell(stemcell_file) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 315
def import_stemcell(stemcell_file)
  req = Net::HTTP::Post::Multipart.new(
    endpoints.import_stemcell_path,
    'stemcell[file]' =>
      UploadIO.new(
        stemcell_file,
        'application/octet-stream',
        File.basename(stemcell_file)
      )
  )

  add_auth_header(req)

  http.request(req)
end
install_log(install_id) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 186
def install_log(install_id)
  get_with_basic_auth(endpoints.installation_log_path(install_id))
end
install_status(install_id) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 182
def install_status(install_id)
  get_with_basic_auth(endpoints.show_installation_status(install_id))
end
installation_delete() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 150
def installation_delete
  req = Net::HTTP::Delete.new(endpoints.installation_path)
  add_auth_header(req)

  http.request(req)
end
installation_deletion_status() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 157
def installation_deletion_status
  get_with_basic_auth(endpoints.installation_deletion_status_path)
end
installation_settings() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 146
def installation_settings
  get_with_basic_auth(endpoints.installation_settings_get_path)
end
installed_products() click to toggle source

products that have been uploaded, configured, and installed

# File lib/opsmgr/api/http_client.rb, line 138
def installed_products
  get_with_basic_auth(endpoints.installed_products_path)
end
list_components() click to toggle source

components are both uploaded AND configured AND deployed

# File lib/opsmgr/api/http_client.rb, line 128
def list_components
  get_with_basic_auth(endpoints.list_components_path)
end
list_products() click to toggle source

products are uploaded but not necessarily configured or deployed

# File lib/opsmgr/api/http_client.rb, line 133
def list_products
  get_with_basic_auth(endpoints.list_products_path)
end
mark_product_for_deletion(product_guid) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 190
def mark_product_for_deletion(product_guid)
  req = Net::HTTP::Delete.new(endpoints.mark_for_deletion_path(product_guid))
  add_auth_header(req)

  http.request(req)
end
product_manifest(product_guid) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 142
def product_manifest(product_guid)
  get_with_basic_auth(endpoints.product_manifest_path(product_guid))
end
read_timeout() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 331
def read_timeout
  environment.settings.dig('iaas_type') != 'vcloud' ? 600 : 3600
end
root_ca_certificate() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 89
def root_ca_certificate
  req = Net::HTTP::Get.new(endpoints.root_ca_certificate_path)
  add_auth_header(req)

  http.request(req)
end
trigger_install() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 119
def trigger_install
  req = Net::HTTP::Post.new(endpoints.install_post_path)
  req.body = ''
  add_auth_header(req)

  http.request(req)
end
upgrade_product(product_guid, to_version) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 104
def upgrade_product(product_guid, to_version)
  req = Net::HTTP::Put.new(endpoints.upgrade_product_path(product_guid))
  req.set_form_data('to_version' => to_version)
  add_auth_header(req)

  http.request(req)
end
upload_component(product_path) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 47
def upload_component(product_path)
  # We ran into a possible Net::HTTP bug where Ruby would always drop the connection while waiting for the
  # uploaded zip file to unzip. Curl behaved correctly, but curb (Ruby bindings for libcurl) did not behave
  # well with WebMock, so here we are.
  upload_component_command =
    %W(
      curl -k
      --silent
      --fail
      #{uri}#{endpoints.upload_product_path}
      -F #{endpoints.upload_product_form_key}[file]=@#{product_path}
      -X POST
    )

  if Gem::Version.new(@om_version) >= Gem::Version.new('1.7')
    log.info('using oauth')
    token = get_oauth_token(web_auth_user)
    upload_component_command.push("-H")
    upload_component_command.push("Authorization: #{token}")
  else
    log.info('using basic auth')
    upload_component_command.push("-u")
    upload_component_command.push("#{web_auth_user}:#{web_auth_password}")
  end

  log.info('uploading product')

  error = nil
  status =
    Open4.popen4(*upload_component_command) do |_, _, stdout, stderr|
      log.info(stdout.read)
      error = stderr.read
    end

  if status.success?
    FakeResponse.new('200', '{}')
  else
    error_code = (error.match(/^\< HTTP\/.* (\d+) /) || [nil, '???'])[1]
    FakeResponse.new(error_code, error)
  end
end
upload_product_installation_settings(settings_file_path) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 31
def upload_product_installation_settings(settings_file_path)
  req = Net::HTTP::Post::Multipart.new(
    endpoints.installation_settings_post_path,
    'installation[file]' =>
      UploadIO.new(
        settings_file_path,
        'application/octet-stream',
        File.basename(settings_file_path)
      )
  )

  add_auth_header(req)

  http.request(req)
end
verify_if_env_admin_user_exists?(token) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 269
def verify_if_env_admin_user_exists?(token)
  request = Net::HTTP::Get.new(
    endpoints.uaa_get_user_by_username_path(web_auth_user)
  )
  request['Authorization'] = token

  response = http.request(request)

  if response.code != '200'
    raise("Invalid response from UAA: #{response.code}")
  end

  reply = JSON.parse(response.body)

  if reply['resources'].nil?
    raise("Invalid response body from UAA: #{response.body}")
  end

  !reply['resources'].empty?
end
version() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 204
def version
  endpoints.version
end
wait_for_uaa_to_be_available(sleep_interval = 10, max_retry_count = 24) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 237
def wait_for_uaa_to_be_available(sleep_interval = 10, max_retry_count = 24)
  retry_count = 0

  loop do
    request = Net::HTTP::Get.new(
      endpoints.login_ensure_availability
    )

    response = http.request(request)

    http_location = response['location']

    break if response.code == '302' && http_location == auth_redirect_location

    retry_count += 1

    if retry_count >= max_retry_count
      retry_wait_time = sleep_interval * retry_count

      raise("Timed out waiting for UAA to be available after #{retry_wait_time} seconds")
    end

    Kernel.sleep(sleep_interval)
  end
end

Private Instance Methods

add_auth_header(request) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 345
def add_auth_header(request)
  if Gem::Version.new(@om_version) >= Gem::Version.new('1.7')
    log.info('using oauth')
    token = get_oauth_token(web_auth_user)
    request['Authorization'] = token
  else
    log.info('using basic auth')
    request.basic_auth(web_auth_user, web_auth_password)
  end
end
get_oauth_token(user) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 356
def get_oauth_token(user)
  target_url = environment.settings.dig('ops_manager', 'url') + '/uaa'
  token_issuer = CF::UAA::TokenIssuer.new(target_url, 'opsman', nil, skip_ssl_validation: true)
  token_issuer.owner_password_grant(user, web_auth_password).auth_header
end
get_with_basic_auth(path) click to toggle source
# File lib/opsmgr/api/http_client.rb, line 380
def get_with_basic_auth(path)
  req = Net::HTTP::Get.new(path)
  add_auth_header(req)

  http.request(req)
end
http() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 370
def http
  http = Net::HTTP.new(uri.host, uri.port)
  if uri.scheme == 'https'
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end
  http.read_timeout = read_timeout
  http
end
web_auth_password() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 366
def web_auth_password
  environment.settings.dig('ops_manager', 'password')
end
web_auth_user() click to toggle source
# File lib/opsmgr/api/http_client.rb, line 362
def web_auth_user
  environment.settings.dig('ops_manager', 'username')
end