11906: healthcheck ping for workbench
authorradhika <radhika@curoverse.com>
Tue, 18 Jul 2017 21:40:21 +0000 (17:40 -0400)
committerradhika <radhika@curoverse.com>
Wed, 19 Jul 2017 14:10:38 +0000 (10:10 -0400)
Arvados-DCO-1.1-Signed-off-by: Radhika Chippada <radhika@curoverse.com>

apps/workbench/app/controllers/healthcheck_controller.rb [new file with mode: 0644]
apps/workbench/config/application.default.yml
apps/workbench/config/routes.rb
apps/workbench/test/controllers/healthcheck_controller_test.rb [new file with mode: 0644]
services/api/app/controllers/arvados/v1/healthcheck_controller.rb
services/api/test/functional/arvados/v1/healthcheck_controller_test.rb

diff --git a/apps/workbench/app/controllers/healthcheck_controller.rb b/apps/workbench/app/controllers/healthcheck_controller.rb
new file mode 100644 (file)
index 0000000..8cf6b93
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+class HealthcheckController < ApplicationController
+  skip_around_filter :thread_clear
+  skip_around_filter :set_thread_api_token
+  skip_around_filter :require_thread_api_token
+  skip_before_filter :ensure_arvados_api_exists
+  skip_before_filter :accept_uuid_as_id_param
+  skip_before_filter :check_user_agreements
+  skip_before_filter :check_user_profile
+  skip_before_filter :load_filters_and_paging_params
+  skip_before_filter :find_object_by_uuid
+
+  before_filter :check_auth_header
+
+  def check_auth_header
+    mgmt_token = Rails.configuration.management_token
+    auth_header = request.headers['Authorization']
+
+    if !mgmt_token
+      render :json => {:errors => "disabled"}, :status => 404
+    elsif !auth_header
+      render :json => {:errors => "authorization required"}, :status => 401
+    elsif auth_header != 'Bearer '+mgmt_token
+      render :json => {:errors => "authorization error"}, :status => 403
+    end
+  end
+
+  def ping
+    resp = {"health" => "OK"}
+    render json: resp
+  end
+end
index 6998b17c9ebbac847bdee224162417d26b7fe033..943432d1670844580a3957a18b7a10ab519113c5 100644 (file)
@@ -295,3 +295,7 @@ common:
   # to suppress these properties
   show_recent_collections_on_dashboard: true
   show_user_notifications: true
+
+  # Token to be included in all healthcheck requests. Disabled by default.
+  # Workbench expects request header of the format "Authorization: Bearer xxx"
+  management_token: false
index f2387f181e6550b6234a835d8fb190a6526072af..a3644e51699871351aecba16ad7dda354695443b 100644 (file)
@@ -126,6 +126,8 @@ ArvadosWorkbench::Application.routes.draw do
 
   root :to => 'projects#index'
 
+  match '/_health/ping', to: 'healthcheck#ping', via: [:get]
+
   # Send unroutable requests to an arbitrary controller
   # (ends up at ApplicationController#render_not_found)
   match '*a', to: 'links#render_not_found', via: [:get, :post]
diff --git a/apps/workbench/test/controllers/healthcheck_controller_test.rb b/apps/workbench/test/controllers/healthcheck_controller_test.rb
new file mode 100644 (file)
index 0000000..9254593
--- /dev/null
@@ -0,0 +1,30 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+require 'test_helper'
+
+class HealthcheckControllerTest < ActionController::TestCase
+  [
+    [false, nil, 404, 'disabled'],
+    [true, nil, 401, 'authorization required'],
+    [true, 'badformatwithnoBearer', 403, 'authorization error'],
+    [true, 'Bearer wrongtoken', 403, 'authorization error'],
+    [true, 'Bearer configuredmanagementtoken', 200, '{"health":"OK"}'],
+  ].each do |enabled, header, error_code, error_msg|
+    test "ping when #{if enabled then 'enabled' else 'disabled' end} with header '#{header}'" do
+      Rails.configuration.management_token = 'configuredmanagementtoken' if enabled
+
+      @request.headers['Authorization'] = header
+      get :ping
+      assert_response error_code
+
+      resp = JSON.parse(@response.body)
+      if error_code == 200
+        assert_equal(JSON.load('{"health":"OK"}'), resp)
+      else
+        assert_equal(resp['errors'], error_msg)
+      end
+    end
+  end
+end
index e10b3936e17e9f4a148d9b826d491b86aac17269..3986af9dc347aebe33ccd8fd26ccd4060eccee77 100644 (file)
@@ -20,11 +20,11 @@ class Arvados::V1::HealthcheckController < ApplicationController
     auth_header = request.headers['Authorization']
 
     if !mgmt_token
-      send_error("disabled", status: 404)
+      send_json ({"errors" => "disabled"}), status: 404
     elsif !auth_header
-      send_error("authorization required", status: 401)
+      send_json ({"errors" => "authorization required"}), status: 401
     elsif auth_header != 'Bearer '+mgmt_token
-      send_error("authorization error", status: 403)
+      send_json ({"errors" => "authorization error"}), status: 403
     end
   end
 
index 10d493b93d4a754e18e3dc4bd6c51118ef4b3a46..282bdf14eb0c3c5b4298927536a1009e541f4f8a 100644 (file)
@@ -23,7 +23,7 @@ class Arvados::V1::HealthcheckControllerTest < ActionController::TestCase
       if error_code == 200
         assert_equal(JSON.load('{"health":"OK"}'), resp)
       else
-        assert_includes(resp['errors'], error_msg)
+        assert_equal(error_msg, resp['errors'])
       end
     end
   end