diff --git a/docs/API.md b/docs/API.md index 038d4e9..8fd8c14 100644 --- a/docs/API.md +++ b/docs/API.md @@ -890,3 +890,23 @@ $ curl -X DELETE https://vmpooler.example.com/api/v1/ondemandvm/e3ff6271-d201-4f "ok": true } ``` + +##### GET /restart + +Restart vmpooler + +An authentication token is required from an authorized user. + +Responses: +* 200 - The restart was successful and status is ok +* 404 - No auth token provided, or provided auth token is not valid + +``` +$ curl -X GET -H X-AUTH-TOKEN:a9znth9dn01t416hrguu56ze37t790bl --url https://vmpooler.example.com/restart +``` +```json +{ + "ok": true + "message": "Restarting ..." +} +``` diff --git a/lib/vmpooler/api.rb b/lib/vmpooler/api.rb index eb856fc..637f13e 100644 --- a/lib/vmpooler/api.rb +++ b/lib/vmpooler/api.rb @@ -3,7 +3,7 @@ module Vmpooler class API < Sinatra::Base # Load API components - %w[helpers dashboard reroute v1 request_logger healthcheck].each do |lib| + %w[helpers dashboard reroute v1 request_logger healthcheck restart].each do |lib| require "vmpooler/api/#{lib}" end # Load dashboard components @@ -44,6 +44,7 @@ module Vmpooler # However, prometheus setup includes the web server which is required for this check # At this time prometheus is a requirement of using the health check on manager use Vmpooler::API::Healthcheck + use Vmpooler::API::Restart, logger: logger end if torun.include? :api @@ -54,6 +55,7 @@ module Vmpooler use Vmpooler::API::Dashboard use Vmpooler::API::Reroute use Vmpooler::API::V1 + use Vmpooler::API::Restart, logger: logger end # Get thee started O WebServer diff --git a/lib/vmpooler/api/restart.rb b/lib/vmpooler/api/restart.rb new file mode 100644 index 0000000..04db951 --- /dev/null +++ b/lib/vmpooler/api/restart.rb @@ -0,0 +1,49 @@ +require 'json' + +module Vmpooler + class API + class Restart < Sinatra::Base + helpers do + include Vmpooler::API::Helpers + end + + # rubocop:disable Lint/MissingSuper + def initialize(app, options = {}) + @app = app + @logger = options[:logger] + end + + def backend + config = Vmpooler.config + redis_host = config[:redis]['server'] + redis_port = config[:redis]['port'] + redis_password = config[:redis]['password'] + Vmpooler.new_redis(redis_host, redis_port, redis_password) + end + + def need_token! + validate_token(backend) + end + + def exit_process + Thread.new do + at_exit do + @logger.log('ignored', 'Restarting VMPooler') + end + sleep(5) + exit! + end + end + + get '/restart/?' do + # token authentication + need_token! + + # restart operation + exit_process + status 200 + JSON.pretty_generate({ 'ok' => true, 'message' => 'Restarting ...' }) + end + end + end +end diff --git a/spec/integration/api/restart_spec.rb b/spec/integration/api/restart_spec.rb new file mode 100644 index 0000000..5c4bb6c --- /dev/null +++ b/spec/integration/api/restart_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' +require 'rack/test' + +describe Vmpooler::API::Restart do + include Rack::Test::Methods + + def app() + Vmpooler::API + end + + # Added to ensure no leakage in rack state from previous tests. + # Removes all routes, filters, middleware and extension hooks from the current class + # https://rubydoc.info/gems/sinatra/Sinatra/Base#reset!-class_method + before(:each) do + app.reset! + end + + + + describe '/restart' do + + it 'returns OK' do + get "/restart" + + expect(last_response.status).to eq(200) + result = JSON.parse(last_response.body) + expect(result).to eq({'ok' => true}) + end + end +end \ No newline at end of file