diff --git a/devops-service/helpers/request.rb b/devops-service/helpers/request.rb index fa967b8..d704827 100644 --- a/devops-service/helpers/request.rb +++ b/devops-service/helpers/request.rb @@ -8,6 +8,7 @@ module Sinatra module Request module Helpers +=begin # Check request headers def check_headers *headers ha = (headers.empty? ? [:accept, :content_type] : headers) @@ -40,6 +41,7 @@ module Sinatra def request_json halt_response("Content-Type should be 'application/json'", 415) if request.media_type.nil? or request.media_type != 'application/json' end +=end end end diff --git a/devops-service/routes/v2.0/bootstrap_templates.rb b/devops-service/routes/v2.0/bootstrap_templates.rb index 501c12e..1e1fc1c 100644 --- a/devops-service/routes/v2.0/bootstrap_templates.rb +++ b/devops-service/routes/v2.0/bootstrap_templates.rb @@ -7,12 +7,6 @@ module Devops def self.registered(app) - app.before "/templates" do - check_headers :accept - check_privileges("templates", "r") -# broadcast(:cancel_order_failed, "hello") - end - # Get list of available bootstrap templates # # * *Request* @@ -24,7 +18,7 @@ module Devops # [ # "omnibus" # ] - app.get "/templates", &Devops::Version2_0::Handler::BootstrapTemplates.get_bootstrap_templates + app.get_with_headers "/templates", :headers => [:accept], &Devops::Version2_0::Handler::BootstrapTemplates.get_bootstrap_templates puts "Bootstrap templates routes initialized" end diff --git a/devops-service/routes/v2.0/group.rb b/devops-service/routes/v2.0/group.rb index 125a28f..ef450f4 100644 --- a/devops-service/routes/v2.0/group.rb +++ b/devops-service/routes/v2.0/group.rb @@ -6,11 +6,6 @@ module Devops def self.registered(app) - app.before "/groups/:provider" do - check_headers :accept - check_privileges("group", "r") - check_provider(params[:provider]) - end # Get security groups for :provider # # * *Request* @@ -49,7 +44,7 @@ module Devops # } # } # TODO: vpc support for ec2 - app.get "/groups/:provider", &Devops::Version2_0::Handler::Group.get_groups + app.get_with_headers "/groups/:provider", :headers => [:accept], &Devops::Version2_0::Handler::Group.get_groups puts "Group routes initialized" end diff --git a/devops-service/routes/v2.0/handlers/bootstrap_templates.rb b/devops-service/routes/v2.0/handlers/bootstrap_templates.rb index 06973b4..90b3cbd 100644 --- a/devops-service/routes/v2.0/handlers/bootstrap_templates.rb +++ b/devops-service/routes/v2.0/handlers/bootstrap_templates.rb @@ -8,6 +8,8 @@ module Devops def self.get_bootstrap_templates lambda { + check_privileges("templates", "r") +# broadcast(:cancel_order_failed, "hello") json BootstrapTemplates.get_templates } end diff --git a/devops-service/routes/v2.0/handlers/group.rb b/devops-service/routes/v2.0/handlers/group.rb index 22570d2..eca44de 100644 --- a/devops-service/routes/v2.0/handlers/group.rb +++ b/devops-service/routes/v2.0/handlers/group.rb @@ -6,6 +6,8 @@ module Devops class Group def self.get_groups lambda { + check_privileges("group", "r") + check_provider(params[:provider]) p = ::Provider::ProviderFactory.get params[:provider] json p.groups(params) } diff --git a/devops-service/routes/v2.0/handlers/key.rb b/devops-service/routes/v2.0/handlers/key.rb index 251b8ef..ab824f6 100644 --- a/devops-service/routes/v2.0/handlers/key.rb +++ b/devops-service/routes/v2.0/handlers/key.rb @@ -5,6 +5,7 @@ module Devops def self.get_keys lambda { + check_privileges("key", "r") keys = settings.mongo.keys.map {|i| i.to_hash} keys.each {|k| k.delete("path")} # We should not return path to the key json keys @@ -13,6 +14,7 @@ module Devops def self.create_key lambda { + check_privileges("key", "w") key = create_object_from_json_body fname = check_filename(key["file_name"], "Parameter 'file_name' must be a not empty string") kname = check_string(key["key_name"], "Parameter 'key_name' should be a not empty string") @@ -32,6 +34,7 @@ module Devops def self.delete_key lambda { + check_privileges("key", "w") servers = settings.mongo.servers_by_key params[:key] unless servers.empty? s_str = servers.map{|s| s.id}.join(", ") diff --git a/devops-service/routes/v2.0/handlers/network.rb b/devops-service/routes/v2.0/handlers/network.rb index 5c3948a..c9b67ed 100644 --- a/devops-service/routes/v2.0/handlers/network.rb +++ b/devops-service/routes/v2.0/handlers/network.rb @@ -7,6 +7,8 @@ module Devops def self.get_networks lambda { + check_privileges("network", "r") + check_provider(params[:provider]) p = ::Provider::ProviderFactory.get params[:provider] json p.networks_detail } diff --git a/devops-service/routes/v2.0/handlers/project.rb b/devops-service/routes/v2.0/handlers/project.rb index 8dcbac1..a818e0d 100644 --- a/devops-service/routes/v2.0/handlers/project.rb +++ b/devops-service/routes/v2.0/handlers/project.rb @@ -15,6 +15,7 @@ module Devops def self.get_projects lambda { + check_privileges("project", "r") fields = [] if params.key?("fields") and params["fields"].is_a?(Array) Project.fields.each do |k| @@ -27,12 +28,14 @@ module Devops def self.get_project lambda { + check_privileges("project", "r") json settings.mongo.project(params[:project]) } end def self.get_project_servers lambda { + check_privileges("project", "r") settings.mongo.project(params[:project]) json settings.mongo.servers(params[:project], params[:deploy_env]).map{|s| s.to_hash} } @@ -41,6 +44,7 @@ module Devops # TODO: multi project def self.create_project lambda { + check_privileges("project", "w") body = create_object_from_json_body check_string(body["name"], "Parameter 'name' must be a not empty string") check_array(body["deploy_envs"], "Parameter 'deploy_envs' must be a not empty array of objects", Hash) @@ -64,6 +68,7 @@ module Devops # TODO: multi project def self.update_project lambda { + check_privileges("project", "w") project = Project.new(create_object_from_json_body) project.id = params[:id] old_project = settings.mongo.project params[:id] @@ -77,10 +82,15 @@ module Devops # TODO: multi project def self.update_project_users lambda { - users = settings.mongo.users(@users).map{|u| u.id} - buf = @users - users - @project.add_authorized_user users, @deploy_env - settings.mongo.project_update(@project) + check_privileges("project", "w") + body = create_object_from_json_body + users = check_array(body["users"], "Parameter 'users' must be a not empty array of strings") + deploy_env = check_string(body["deploy_env"], "Parameter 'deploy_env' must be a not empty string", true) + project = settings.mongo.project(params[:id]) + users = settings.mongo.users(users).map{|u| u.id} + buf = users - users + project.add_authorized_user users, deploy_env + settings.mongo.project_update(project) info = "Users '#{users.join("', '")}' have been added to '#{params[:id]}' project's authorized users" info << ", invalid users: '#{buf.join("', '")}'" unless buf.empty? create_response(info) @@ -90,6 +100,7 @@ module Devops # TODO: multi project def self.delete_project_users lambda { + check_privileges("project", "w") @project.remove_authorized_user @users, @deploy_env settings.mongo.project_update @project info = "Users '#{@users.join("', '")}' have been removed from '#{params[:id]}' project's authorized users" @@ -100,6 +111,7 @@ module Devops # TODO: multi project def self.set_project_env_run_list lambda { + check_privileges("project", "w") list = create_object_from_json_body(Array) check_array(list, "Body must contains not empty array of strings") project = settings.mongo.project(params[:id]) @@ -112,6 +124,7 @@ module Devops def self.delete_project lambda { + check_privileges("project", "w") servers = settings.mongo.servers params[:id] raise DependencyError.new "Deleting #{params[:id]} is forbidden: Project has servers" if !servers.empty? body = create_object_from_json_body(Hash, true) @@ -133,6 +146,7 @@ module Devops def self.deploy_project lambda { + check_privileges("project", "x") obj = create_object_from_json_body check_string(obj["deploy_env"], "Parameter 'deploy_env' should be a not empty string", true) check_array(obj["servers"], "Parameter 'servers' should be a not empty array of strings", String, true) @@ -187,6 +201,7 @@ module Devops def self.test_project lambda { + check_privileges("project", "r") project = settings.mongo.project(params[:id]) env = project.deploy_env params[:env] logger.info "Test project '#{project.id}' and environment '#{env.identifier}'" diff --git a/devops-service/routes/v2.0/handlers/provider.rb b/devops-service/routes/v2.0/handlers/provider.rb index bf36a29..a777dc6 100644 --- a/devops-service/routes/v2.0/handlers/provider.rb +++ b/devops-service/routes/v2.0/handlers/provider.rb @@ -6,6 +6,7 @@ module Devops class Provider def self.get_providers lambda { + check_privileges("provider", "r") json ::Provider::ProviderFactory.providers } end diff --git a/devops-service/routes/v2.0/handlers/script.rb b/devops-service/routes/v2.0/handlers/script.rb index 230896f..7b53e16 100644 --- a/devops-service/routes/v2.0/handlers/script.rb +++ b/devops-service/routes/v2.0/handlers/script.rb @@ -9,6 +9,7 @@ module Devops def self.get_scripts lambda { + check_privileges("script", "r") res = [] Dir.foreach(DevopsService.config[:scripts_dir]) {|f| res.push(f) unless f.start_with?(".")} json res @@ -17,6 +18,7 @@ module Devops def self.execute_command lambda { + check_privileges("script", "x") user = request.env['REMOTE_USER'] s = ::Devops::Db.connector.server_by_chef_node_name params[:node_name] ::Devops::Db.connector.check_project_auth s.project, s.deploy_env, user @@ -43,6 +45,7 @@ module Devops def self.run_script lambda { + check_privileges("script", "x") file_name = params[:script_name] @file = File.join(DevopsService.config[:scripts_dir], check_filename(file_name, "Parameter 'script_name' must be a not empty string", false)) halt(404, "File '#{file_name}' does not exist") unless File.exists?(@file) @@ -98,14 +101,22 @@ module Devops def self.create_script lambda { - File.open(@file, "w") {|f| f.write(request.body.read)} + check_privileges("script", "w") + file_name = params[:script_name] + file = File.join(DevopsService.config[:scripts_dir], check_filename(file_name, "Parameter 'script_name' must be a not empty string")) + halt_response("File '#{file_name}' already exist") if File.exists?(file) + File.open(file, "w") {|f| f.write(request.body.read)} create_response("File '#{params[:script_name]}' created", nil, 201) } end def self.delete_script lambda { - FileUtils.rm(@file) + check_privileges("script", "w") + file_name = params[:script_name] + file = File.join(DevopsService.config[:scripts_dir], check_filename(file_name, "Parameter 'script_name' must be a not empty string")) + halt_response("File '#{file_name}' does not exist", 404) unless File.exists?(file) + FileUtils.rm(file) create_response("File '#{params[:script_name]}' deleted") } end diff --git a/devops-service/routes/v2.0/handlers/server.rb b/devops-service/routes/v2.0/handlers/server.rb index 2f912ce..28e2c68 100644 --- a/devops-service/routes/v2.0/handlers/server.rb +++ b/devops-service/routes/v2.0/handlers/server.rb @@ -26,6 +26,7 @@ module Devops def self.get_servers lambda { + check_privileges("server", "r") fields = [] if params.key?("fields") and params["fields"].is_a?(Array) Server.fields.each do |k| @@ -39,24 +40,28 @@ module Devops def self.get_chef_servers lambda { + check_privileges("server", "r") json KnifeCommands.chef_node_list } end def self.get_provider_servers lambda { + check_privileges("server", "r") json ::Provider::ProviderFactory.get(params[:provider]).servers } end def self.get_server lambda { + check_privileges("server", "r") json Server.get_server_by_key(params[:name], params[:key]).to_hash } end def self.delete_server lambda { + check_privileges("server", "w") body = create_object_from_json_body(Hash, true) key = (body.nil? ? nil : body["key"]) s = Server.get_server_by_key(params[:id], key) @@ -69,6 +74,7 @@ module Devops def self.create_server lambda { + check_privileges("server", "w") body = create_object_from_json_body user = request.env['REMOTE_USER'] project_name = check_string(body["project"], "Parameter 'project' must be a not empty string") @@ -126,7 +132,10 @@ module Devops def self.pause_server lambda { - s = Server.get_server_by_key(params[:node_name], @key) + check_privileges("server", "w") + body = create_object_from_json_body(Hash, true) + key = (body.nil? ? nil : body["key"]) + s = Server.get_server_by_key(params[:node_name], key) ## Authorization settings.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER'] provider = ::Provider::ProviderFactory.get(s.provider) @@ -141,7 +150,10 @@ module Devops def self.unpause_server lambda { - s = Server.get_server_by_key(params[:node_name], @key) + check_privileges("server", "w") + body = create_object_from_json_body(Hash, true) + key = (body.nil? ? nil : body["key"]) + s = Server.get_server_by_key(params[:node_name], key) ## Authorization settings.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER'] provider = ::Provider::ProviderFactory.get(s.provider) @@ -157,7 +169,10 @@ module Devops def self.reserve_server lambda { - s = Server.get_server_by_key(params[:node_name], params[:key]) + check_privileges("server", "w") + body = create_object_from_json_body(Hash, true) + key = (body.nil? ? nil : body["key"]) + s = Server.get_server_by_key(params[:node_name], key) user = request.env['REMOTE_USER'] settings.mongo.check_project_auth s.project, s.deploy_env, user halt_response(400, "Server '#{params[:node_name]}' already reserved") unless s.reserved_by.nil? @@ -170,7 +185,10 @@ module Devops def self.unreserve_server lambda { - s = Server.get_server_by_key(params[:node_name], params[:key]) + check_privileges("server", "w") + body = create_object_from_json_body(Hash, true) + key = (body.nil? ? nil : body["key"]) + s = Server.get_server_by_key(params[:node_name], key) settings.mongo.check_project_auth s.project, s.deploy_env, request.env['REMOTE_USER'] halt_response(400, "Server '#{params[:node_name]}' is not reserved") if s.reserved_by.nil? s.reserved_by = nil @@ -182,6 +200,7 @@ module Devops # TODO: check bootstrap template name def self.bootstrap_server lambda { + check_privileges("server", "w") body = create_object_from_json_body(Hash, true) id = check_string(body["instance_id"], "Parameter 'instance_id' must be a not empty string") name = check_string(body["name"], "Parameter 'name' should be a not empty string", true) @@ -256,6 +275,7 @@ module Devops def self.add_server lambda { + check_privileges("server", "w") body = create_object_from_json_body project = check_string(body["project"], "Parameter 'project' must be a not empty string") deploy_env = check_string(body["deploy_env"], "Parameter 'deploy_env' must be a not empty string") diff --git a/devops-service/routes/v2.0/handlers/tag.rb b/devops-service/routes/v2.0/handlers/tag.rb index 6b0c647..9198aac 100644 --- a/devops-service/routes/v2.0/handlers/tag.rb +++ b/devops-service/routes/v2.0/handlers/tag.rb @@ -7,25 +7,41 @@ module Devops def self.get_tags lambda { - json(KnifeCommands.tags_list(@chef_node_name)) + check_privileges("server", "r") + server = settings.mongo.server_by_chef_node_name(params[:node_name]) + halt_response("No servers found for name '#{params[:node_name]}'", 404) if server.nil? + chef_node_name = server.chef_node_name + json(KnifeCommands.tags_list(chef_node_name)) } end def self.set_tags lambda { - tagsStr = @tags.join(" ") - cmd = KnifeCommands.tags_create(@chef_node_name, tagsStr) - halt_response("Error: Cannot add tags #{tagsStr} to server #{@chef_node_name}", 500) unless cmd[1] - create_response("Set tags for #{@chef_node_name}: #{tagsStr}") + check_privileges("server", "w") + tags = create_object_from_json_body(Array) + check_array(tags, "Request body should be a not empty array of strings") + server = settings.mongo.server_by_chef_node_name(params[:node_name]) + halt_response("No servers found for name '#{params[:node_name]}'", 404) if server.nil? + chef_node_name = server.chef_node_name + tagsStr = tags.join(" ") + cmd = KnifeCommands.tags_create(chef_node_name, tagsStr) + halt_response("Error: Cannot add tags #{tagsStr} to server #{chef_node_name}", 500) unless cmd[1] + create_response("Set tags for #{chef_node_name}: #{tagsStr}") } end def self.unset_tags lambda { - tagsStr = @tags.join(" ") - cmd = KnifeCommands.tags_delete(@chef_node_name, tagsStr) - halt_response("Cannot delete tags #{tagsStr} from server #{@chef_node_name}: #{cmd[0]}", 500) unless cmd[1] - create_response("Deleted tags for #{@chef_node_name}: #{tagsStr}") + check_privileges("server", "w") + tags = create_object_from_json_body(Array) + check_array(tags, "Request body should be a not empty array of strings") + server = settings.mongo.server_by_chef_node_name(params[:node_name]) + halt_response("No servers found for name '#{params[:node_name]}'", 404) if server.nil? + chef_node_name = server.chef_node_name + tagsStr = tags.join(" ") + cmd = KnifeCommands.tags_delete(chef_node_name, tagsStr) + halt_response("Cannot delete tags #{tagsStr} from server #{chef_node_name}: #{cmd[0]}", 500) unless cmd[1] + create_response("Deleted tags for #{chef_node_name}: #{tagsStr}") } end end diff --git a/devops-service/routes/v2.0/handlers/user.rb b/devops-service/routes/v2.0/handlers/user.rb index 769170b..33b4feb 100644 --- a/devops-service/routes/v2.0/handlers/user.rb +++ b/devops-service/routes/v2.0/handlers/user.rb @@ -8,6 +8,7 @@ module Devops def self.get_users lambda { + check_privileges("user", "r") users = settings.mongo.users.map {|i| i.to_hash} users.each {|u| u.delete("password")} json users @@ -16,6 +17,7 @@ module Devops def self.create_user lambda { + check_privileges("user", "w") user = create_object_from_json_body ["username", "password", "email"].each do |p| check_string(user[p], "Parameter '#{p}' must be a not empty string") @@ -27,6 +29,7 @@ module Devops def self.delete_user lambda { + check_privileges("user", "w") projects = settings.mongo.projects_by_user params[:user] if !projects.empty? str = "" @@ -47,6 +50,7 @@ module Devops def self.change_user_privileges lambda { + check_privileges("user", "w") data = create_object_from_json_body user = settings.mongo.user params[:user] cmd = check_string(data["cmd"], "Parameter 'cmd' should be a not empty string", true) || "" @@ -59,6 +63,7 @@ module Devops def self.change_user_email_or_password lambda { + check_privileges("user", "w") action = File.basename(request.path) u = File.basename(File.dirname(request.path)) raise InvalidPrivileges.new("Access denied for '#{request.env['REMOTE_USER']}'") if u == User::ROOT_USER_NAME and request.env['REMOTE_USER'] != User::ROOT_USER_NAME diff --git a/devops-service/routes/v2.0/key.rb b/devops-service/routes/v2.0/key.rb index c5acecd..956b25f 100644 --- a/devops-service/routes/v2.0/key.rb +++ b/devops-service/routes/v2.0/key.rb @@ -9,25 +9,6 @@ module Devops module KeyRoutes def self.registered(app) - - app.after %r{\A/key(/[\w]+)?\z} do - statistic - end - - app.before "/keys" do - check_headers :accept - check_privileges("key", "r") - end - - app.before "/key" do - check_headers :accept, :content_type - check_privileges("key", "w") - end - - app.before "/key/:key" do - check_headers :accept - check_privileges("key", "w") - end # Get list of available ssh keys # # * *Request* @@ -42,7 +23,7 @@ module Devops # "id": "devops" # } # ] - app.get "/keys", &Devops::Version2_0::Handler::Key.get_keys + app.get_with_headers "/keys", :headers => [:accept], &Devops::Version2_0::Handler::Key.get_keys # Create ssh key on devops server # @@ -60,7 +41,7 @@ module Devops # # * *Returns* : # 201 - Created - app.post "/key", &Devops::Version2_0::Handler::Key.create_key + app.post_with_headers "/key", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::Key.create_key # Delete ssh key from devops server # @@ -71,7 +52,7 @@ module Devops # # * *Returns* : # 200 - Deleted - app.delete "/key/:key", &Devops::Version2_0::Handler::Key.delete_key + app.delete_with_headers "/key/:key", :headers => [:accept], &Devops::Version2_0::Handler::Key.delete_key puts "Key routes initialized" end diff --git a/devops-service/routes/v2.0/network.rb b/devops-service/routes/v2.0/network.rb index 27dafbe..88537fc 100644 --- a/devops-service/routes/v2.0/network.rb +++ b/devops-service/routes/v2.0/network.rb @@ -6,11 +6,6 @@ module Devops def self.registered(app) - app.before "/networks/:provider" do - check_headers :accept - check_privileges("network", "r") - check_provider(params[:provider]) - end # Get list of networks for :provider # # * *Request* @@ -37,7 +32,7 @@ module Devops # "id": "b14f8df9-ac27-48e2-8d65-f7ef78dc2654" # } # ] - app.get "/networks/:provider", &Devops::Version2_0::Handler::Network.get_networks + app.get "/networks/:provider", :headers => [:accept], &Devops::Version2_0::Handler::Network.get_networks puts "Network routes initialized" end diff --git a/devops-service/routes/v2.0/project.rb b/devops-service/routes/v2.0/project.rb index 7dd7fd1..78b98cd 100644 --- a/devops-service/routes/v2.0/project.rb +++ b/devops-service/routes/v2.0/project.rb @@ -5,23 +5,6 @@ module Devops def self.registered(app) - app.before "/project/:id/user" do - check_headers :accept, :content_type - check_privileges("project", "w") - body = create_object_from_json_body - @users = check_array(body["users"], "Parameter 'users' must be a not empty array of strings") - @deploy_env = check_string(body["deploy_env"], "Parameter 'deploy_env' must be a not empty string", true) - @project = settings.mongo.project(params[:id]) - end - - app.after %r{\A/project(/[\w]+(/(user|deploy))?)?\z} do - statistic - end - - app.after "/project/:id/:env/run_list" do - statistic - end - # Get projects list # # * *Request* @@ -35,11 +18,7 @@ module Devops # [ # {"name" : "project_1"} # ] - app.before "/projects" do - check_headers :accept - check_privileges("project", "r") - end - app.get "/projects", &Devops::Version2_0::Handler::Project.get_projects + app.get_with_headers "/projects", :headers => [:accept], &Devops::Version2_0::Handler::Project.get_projects # Get project by id # @@ -73,91 +52,8 @@ module Devops # ], # "name": "project_1" # } - app.before "/project/:project" do - if request.get? - check_headers :accept - check_privileges("project", "r") - elsif request.put? or request.delete? - check_headers - check_privileges("project", "w") - else - return [404, "Route not found"] - end - end - app.get "/project/:project", &Devops::Version2_0::Handler::Project.get_project - - # Get project servers - # - # * *Request* - # - method : GET - # - headers : - # - Accept: application/json - # - parameters : - # - deploy_env=:env -> show servers with environment :env - # - # * *Returns* : - # [ - # { - # "provider": "openstack", - # "chef_node_name": "project_1_server", - # "remote_user": "root", - # "project": "project_1", - # "deploy_env": "prod", - # "private_ip": "10.8.8.8", - # "public_ip": null, - # "created_at": "2014-04-23 13:35:18 UTC", - # "created_by": "user", - # "static": false, - # "key": "ssh key", - # "id": "nstance id" - # } - # ] - app.before "/project/:project/servers" do - check_headers :accept - check_privileges("project", "r") - end - app.get "/project/:project/servers", &Devops::Version2_0::Handler::Project.get_project_servers - - # Create project and chef roles - # - # * *Request* - # - method : POST - # - headers : - # - Accept: application/json - # - Content-Type: application/json - # - body : - # { - # "deploy_envs": [ - # { - # "identifier": "prod", - # "provider": "openstack", - # "flavor": "m1.small", - # "image": "image id", - # "subnets": [ - # "private" - # ], - # "groups": [ - # "default" - # ], - # "users": [ - # "user" - # ], - # "run_list": [ - # - # ], - # "expires": null - # } - # ], - # "name": "project_1" - # } - # - # * *Returns* : - # 201 - Created - app.before "/project" do - check_headers :accept, :content_type - check_privileges("project", "w") - end - app.post "/project", &Devops::Version2_0::Handler::Project.create_project + hash = {} + hash["GET"] = Devops::Version2_0::Handler::Project.get_project # Update project and create chef roles # @@ -194,8 +90,91 @@ module Devops # # * *Returns* : # 200 - Updated - app.put "/project/:id", &Devops::Version2_0::Handler::Project.update_project + hash["PUT"] = Devops::Version2_0::Handler::Project.update_project + # Delete project + # + # * *Request* + # - method : DELETE + # - headers : + # - Accept: application/json + # - Content-Type: application/json + # - body : + # { + # "deploy_env": "env" -> if not null, will be deleted environment only + # } + # + # * *Returns* : + # 200 - Deleted + hash["DELETE"] = Devops::Version2_0::Handler::Project.delete_project + app.multi_routes "/project/:id", {}, hash + + # Get project servers + # + # * *Request* + # - method : GET + # - headers : + # - Accept: application/json + # - parameters : + # - deploy_env=:env -> show servers with environment :env + # + # * *Returns* : + # [ + # { + # "provider": "openstack", + # "chef_node_name": "project_1_server", + # "remote_user": "root", + # "project": "project_1", + # "deploy_env": "prod", + # "private_ip": "10.8.8.8", + # "public_ip": null, + # "created_at": "2014-04-23 13:35:18 UTC", + # "created_by": "user", + # "static": false, + # "key": "ssh key", + # "id": "nstance id" + # } + # ] + app.get_with_headers "/project/:project/servers", :headers => [:accept], &Devops::Version2_0::Handler::Project.get_project_servers + + # Create project and chef roles + # + # * *Request* + # - method : POST + # - headers : + # - Accept: application/json + # - Content-Type: application/json + # - body : + # { + # "deploy_envs": [ + # { + # "identifier": "prod", + # "provider": "openstack", + # "flavor": "m1.small", + # "image": "image id", + # "subnets": [ + # "private" + # ], + # "groups": [ + # "default" + # ], + # "users": [ + # "user" + # ], + # "run_list": [ + # + # ], + # "expires": null + # } + # ], + # "name": "project_1" + # } + # + # * *Returns* : + # 201 - Created + app.post_with_headers "/project", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::Project.create_project + + users_hash = {} # Add users to project environment # # * *Request* @@ -213,7 +192,7 @@ module Devops # # * *Returns* : # 200 - Updated - app.put "/project/:id/user", &Devops::Version2_0::Handler::Project.update_project_users + users_hash["PUT"] = Devops::Version2_0::Handler::Project.update_project_users # Delete users from project environment # @@ -232,7 +211,8 @@ module Devops # # * *Returns* : # 200 - Updated - app.delete "/project/:id/user", &Devops::Version2_0::Handler::Project.delete_project_users + users_hash["DELETE"] = Devops::Version2_0::Handler::Project.delete_project_users + app.multi_routes "/project/:id/user", {}, users_hash # Set run_list to project environment # @@ -249,27 +229,7 @@ module Devops # # * *Returns* : # 200 - Updated - app.before "/project/:id/:env/run_list" do - check_headers :accept, :content_type - check_privileges("project", "w") - end - app.put "/project/:id/:env/run_list", &Devops::Version2_0::Handler::Project.set_project_env_run_list - - # Delete project - # - # * *Request* - # - method : DELETE - # - headers : - # - Accept: application/json - # - Content-Type: application/json - # - body : - # { - # "deploy_env": "env" -> if not null, will be deleted environment only - # } - # - # * *Returns* : - # 200 - Deleted - app.delete "/project/:id", &Devops::Version2_0::Handler::Project.delete_project + app.put_with_headers "/project/:id/:env/run_list", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::Project.set_project_env_run_list # Run chef-client on reserved project servers # @@ -286,11 +246,7 @@ module Devops # } # # * *Returns* : text stream - app.before "/project/:id/deploy" do - check_headers :content_type - check_privileges("project", "x") - end - app.post "/project/:id/deploy", &Devops::Version2_0::Handler::Project.deploy_project + app.post_with_headers "/project/:id/deploy", :headers => [:content_type], &Devops::Version2_0::Handler::Project.deploy_project # Test project environment # @@ -358,11 +314,7 @@ module Devops # }, # "message": "Test project 'project_1' and environment 'prod'" # } - app.before "/project/test/:id/:env" do - check_headers :accept, :content_type - check_privileges("project", "r") - end - app.post "/project/test/:id/:env", &Devops::Version2_0::Handler::Project.test_project + app.post_with_headers "/project/test/:id/:env", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::Project.test_project puts "Project routes initialized" end diff --git a/devops-service/routes/v2.0/provider.rb b/devops-service/routes/v2.0/provider.rb index d99c99a..ab48ced 100644 --- a/devops-service/routes/v2.0/provider.rb +++ b/devops-service/routes/v2.0/provider.rb @@ -10,11 +10,6 @@ module Devops def self.registered(app) - app.before "/providers" do - check_headers :accept - check_privileges("provider", "r") - end - # Get devops providers # # * *Request* @@ -27,7 +22,7 @@ module Devops # "ec2", # "openstack" # ] - app.get "/providers", &Devops::Version2_0::Handler::Provider.get_providers + app.get_with_headers "/providers", :headers => [:accept], &Devops::Version2_0::Handler::Provider.get_providers puts "Provider routes initialized" end diff --git a/devops-service/routes/v2.0/script.rb b/devops-service/routes/v2.0/script.rb index 2addddb..c52f724 100644 --- a/devops-service/routes/v2.0/script.rb +++ b/devops-service/routes/v2.0/script.rb @@ -5,22 +5,6 @@ module Devops module ScriptRoutes def self.registered(app) - app.before "/script/:script_name" do - check_headers :accept - check_privileges("script", "w") - file_name = params[:script_name] - @file = File.join(DevopsService.config[:scripts_dir], check_filename(file_name, "Parameter 'script_name' must be a not empty string")) - if request.put? - halt_response("File '#{file_name}' already exist") if File.exists?(@file) - elsif request.delete? - halt_response("File '#{file_name}' does not exist", 404) unless File.exists?(@file) - end - end - - app.after %r{\A/script/((command|run)/)?[\w]+\z} do - statistic - end - # Get scripts names # # * *Request* @@ -32,11 +16,7 @@ module Devops # [ # "script_1" # ] - app.before "/scripts" do - check_headers :accept - check_privileges("script", "r") - end - app.get "/scripts", &Devops::Version2_0::Handler::Script.get_scripts + app.get_with_headers "/scripts", :headers => [:accept], &Devops::Version2_0::Handler::Script.get_scripts # Run command on node :node_name # @@ -46,10 +26,7 @@ module Devops # command to run # # * *Returns* : text stream - app.before "/script/command/:node_name" do - check_privileges("script", "x") - end - app.post "/script/command/:node_name", &Devops::Version2_0::Handler::Script.execute_command + app.post_with_statistic "/script/command/:node_name", &Devops::Version2_0::Handler::Script.execute_command # Run script :script_name on nodes # @@ -64,12 +41,9 @@ module Devops # } # # * *Returns* : text stream - app.before "/script/run/:script_name" do - check_headers :content_type - check_privileges("script", "x") - end - app.post "/script/run/:script_name", &Devops::Version2_0::Handler::Script.run_script + app.post_with_headers "/script/run/:script_name", :headers => [:content_type], &Devops::Version2_0::Handler::Script.run_script + hash = {} # Create script :script_name # # * *Request* @@ -80,7 +54,7 @@ module Devops # # * *Returns* : # 201 - Created - app.put "/script/:script_name", &Devops::Version2_0::Handler::Script.create_script + hash["PUT"] = Devops::Version2_0::Handler::Script.create_script # Delete script :script_name # @@ -91,7 +65,8 @@ module Devops # # * *Returns* : # 200 - Deleted - app.delete "/script/:script_name", &Devops::Version2_0::Handler::Script.delete_script + hash["DELETE"] = Devops::Version2_0::Handler::Script.delete_script + app.multi_routes "/script/:script_name", {:headers => [:accept]}, hash puts "Script routes initialized" end diff --git a/devops-service/routes/v2.0/server.rb b/devops-service/routes/v2.0/server.rb index 20723e4..bf1c13f 100644 --- a/devops-service/routes/v2.0/server.rb +++ b/devops-service/routes/v2.0/server.rb @@ -6,16 +6,6 @@ module Devops module ServerRoutes def self.registered(app) - app.before %r{\A/server/[\w]+/(pause|unpouse|reserve|unreserve)\z} do - check_headers :accept, :content_type - check_privileges("server", "w") - body = create_object_from_json_body(Hash, true) - @key = (body.nil? ? nil : body["key"]) - end - - app.after %r{\A/server(/[\w]+)?\z | \A/server/(add|bootstrap)\z | \A/server/[\w]+/(un)?pause\z} do - statistic - end # Get devops servers list # @@ -33,11 +23,7 @@ module Devops # "chef_node_name": "chef name" # } # ] - app.before "/servers" do - check_headers :accept - check_privileges("server", "r") - end - app.get "/servers", &Devops::Version2_0::Handler::Server.get_servers + app.get_with_headers "/servers", :headers => [:accept], &Devops::Version2_0::Handler::Server.get_servers # Get chef nodes list # @@ -52,11 +38,7 @@ module Devops # "chef_node_name": "chef name" # } # ] - app.before "/servers/chef" do - check_headers :accept - check_privileges("server", "r") - end - app.get "/servers/chef", &Devops::Version2_0::Handler::Server.get_chef_servers + app.get_with_headers "/servers/chef", :headers => [:accept], &Devops::Version2_0::Handler::Server.get_chef_servers # Get provider servers list # @@ -94,11 +76,7 @@ module Devops # "private_ip": "172.17.0.1" # } # ] - app.before "/servers/:provider" do - check_headers :accept - check_privileges("server", "r") - end - app.get "/servers/:provider", &Devops::Version2_0::Handler::Server.get_provider_servers + app.get_with_headers "/servers/:provider", :headers => [:accept], &Devops::Version2_0::Handler::Server.get_provider_servers # Get server info by :name # @@ -115,16 +93,8 @@ module Devops # "chef_node_name": "chef name" # } # ] - app.before "/server/:name" do - if request.get? - check_headers :accept - check_privileges("server", "r") - elsif request.delete? - check_headers - check_privileges("server", "w") - end - end - app.get "/server/:name", &Devops::Version2_0::Handler::Server.get_server + hash = {} + hash["GET"] = Devops::Version2_0::Handler::Server.get_server # Delete devops server # @@ -140,7 +110,8 @@ module Devops # # * *Returns* : # 200 - Deleted - app.delete "/server/:id", &Devops::Version2_0::Handler::Server.delete_server + hash["DELETE"] = Devops::Version2_0::Handler::Server.delete_server + app.multi_routes "/server/:id", {:headers => [:accept, :content_type]}, hash # Create devops server # @@ -162,11 +133,7 @@ module Devops # } # # * *Returns* : text stream - app.before "/server" do - check_headers :content_type - check_privileges("server", "w") - end - app.post "/server", &Devops::Version2_0::Handler::Server.create_server + app.post_with_headers "/server", :headers => [:content_type], &Devops::Version2_0::Handler::Server.create_server # Pause devops server by name # @@ -182,7 +149,7 @@ module Devops # # * *Returns* : # 200 - Paused - app.post "/server/:node_name/pause", &Devops::Version2_0::Handler::Server.pause_server + app.post_with_headers "/server/:node_name/pause", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::Server.pause_server # Unpause devops server by name # @@ -198,7 +165,7 @@ module Devops # # * *Returns* : # 200 - Unpaused - app.post "/server/:node_name/unpause", &Devops::Version2_0::Handler::Server.unpause_server + app.post_with_headers "/server/:node_name/unpause", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::Server.unpause_server # Reserve devops server # @@ -214,7 +181,7 @@ module Devops # # * *Returns* : # 200 - Reserved - app.post "/server/:node_name/reserve", &Devops::Version2_0::Handler::Server.reserve_server + app.post_with_headers "/server/:node_name/reserve", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::Server.reserve_server # Unreserve devops server # @@ -230,7 +197,7 @@ module Devops # # * *Returns* : # 200 - Unreserved - app.post "/server/:node_name/unreserve", &Devops::Version2_0::Handler::Server.unreserve_server + app.post_with_headers "/server/:node_name/unreserve", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::Server.unreserve_server # Bootstrap devops server # @@ -248,11 +215,7 @@ module Devops # } # # * *Returns* : text stream - app.before "/server/bootstrap" do - check_headers - check_privileges("server", "w") - end - app.post "/server/bootstrap", &Devops::Version2_0::Handler::Server.bootstrap_server + app.post_with_headers "/server/bootstrap", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::Server.bootstrap_server # Add external server to devops # @@ -273,11 +236,7 @@ module Devops # # * *Returns* : # 200 - Added - app.before "/server/add" do - check_headers - check_privileges("server", "w") - end - app.post "/server/add", &Devops::Version2_0::Handler::Server.add_server + app.post_with_headers "/server/add", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::Server.add_server puts "Server routes initialized" end diff --git a/devops-service/routes/v2.0/tag.rb b/devops-service/routes/v2.0/tag.rb index 83fb1d7..d7577b9 100644 --- a/devops-service/routes/v2.0/tag.rb +++ b/devops-service/routes/v2.0/tag.rb @@ -4,25 +4,8 @@ module Devops module TagRoutes def self.registered(app) - app.before "/tags/:node_name" do - if request.get? - check_headers :accept - check_privileges("server", "r") - else - check_headers :accept, :content_type - check_privileges("server", "w") - @tags = create_object_from_json_body(Array) - check_array(@tags, "Request body should be a not empty array of strings") - end - server = settings.mongo.server_by_chef_node_name(params[:node_name]) - halt_response("No servers found for name '#{params[:node_name]}'", 404) if server.nil? - @chef_node_name = server.chef_node_name - end - - app.after "/tags/:node_name" do - statistic - end + hash = {} # Get tags list for :node_name # # * *Request* @@ -34,7 +17,7 @@ module Devops # [ # "tag_1" # ] - app.get "/tags/:node_name", &Devops::Version2_0::Handler::Tag.get_tags + hash["GET"] = Devops::Version2_0::Handler::Tag.get_tags # Set tags list to :node_name # @@ -50,7 +33,7 @@ module Devops # # * *Returns* : # 200 - app.post "/tags/:node_name", &Devops::Version2_0::Handler::Tag.set_tags + hash["POST"] = Devops::Version2_0::Handler::Tag.set_tags # Delete tags from :node_name # @@ -66,7 +49,8 @@ module Devops # # * *Returns* : # 200 - app.delete "/tags/:node_name", &Devops::Version2_0::Handler::Tag.unset_tags + hash["DELETE"] = Devops::Version2_0::Handler::Tag.unset_tags + app.multi_routes "/tags/:node_name", {:headers => [:accept, :content_type]}, hash puts "Tag routes initialized" end diff --git a/devops-service/routes/v2.0/user.rb b/devops-service/routes/v2.0/user.rb index f8534fb..5a3ea28 100644 --- a/devops-service/routes/v2.0/user.rb +++ b/devops-service/routes/v2.0/user.rb @@ -5,10 +5,6 @@ module Devops def self.registered(app) - app.after %r{\A/user(/[\w]+(/password)?)?\z} do - statistic - end - # Get users list # # * *Request* @@ -37,11 +33,7 @@ module Devops # "id": "test" # } # ] - app.before "/users" do - check_headers :accept - check_privileges("user", "r") - end - app.get "/users", &Devops::Version2_0::Handler::User.get_users + app.get_with_headers "/users", :headers => [:accept], &Devops::Version2_0::Handler::User.get_users # Create user # @@ -59,12 +51,9 @@ module Devops # # * *Returns* : # 201 - Created - app.before "/user" do - check_headers :accept, :content_type - check_privileges("user", "w") - end - app.post "/user", &Devops::Version2_0::Handler::User.create_user + app.post_with_headers "/user", :headers => [:accept, :content_type], &Devops::Version2_0::Handler::User.create_user + hash = {} # Delete user # # * *Request* @@ -74,15 +63,7 @@ module Devops # # * *Returns* : # 200 - Deleted - app.before "/user/:user" do - if request.delete? - check_headers :accept - elsif request.put? - check_headers :accept, :content_type - end - check_privileges("user", "w") - end - app.delete "/user/:user", &Devops::Version2_0::Handler::User.delete_user + hash["DELETE"] = Devops::Version2_0::Handler::User.delete_user # Change user privileges # @@ -99,7 +80,8 @@ module Devops # # * *Returns* : # 200 - Updated - app.put "/user/:user", &Devops::Version2_0::Handler::User.change_user_privileges + hash["PUT"] = Devops::Version2_0::Handler::User.change_user_privileges + app.multi_routes "/user/:user", {:headers => [:accept, :content_type]}, hash # Change user email/password # @@ -115,10 +97,7 @@ module Devops # # * *Returns* : # 200 - Updated - app.before %r{\A/user/[\w]+/(email|password)\z} do - check_headers :accept, :content_type - end - app.put %r{\A/user/[\w]+/(email|password)\z}, &Devops::Version2_0::Handler::User.change_user_email_or_password + app.put_with_headers %r{\A/user/#{DevopsConfig::OBJECT_NAME}/(email|password)\z}, :headers => [:accept, :content_type], &Devops::Version2_0::Handler::User.change_user_email_or_password puts "User routes initialized" end diff --git a/devops-service/sinatra/methods_with_headers.rb b/devops-service/sinatra/methods_with_headers.rb index 5e05c82..b5cfaa8 100644 --- a/devops-service/sinatra/methods_with_headers.rb +++ b/devops-service/sinatra/methods_with_headers.rb @@ -26,7 +26,10 @@ module Sinatra before path do check_headers *headers end + post_with_statistic path, opt, &block + end + def post_with_statistic path, opt={}, &block post path, opt, &block after path do @@ -63,7 +66,11 @@ module Sinatra def multi_routes path, opts={}, hash={} headers = opt.delete(:headers) || [] before path do - check_headers *headers + if request.get? + check_headers :accept + else + check_headers *headers + end end hash.each do |method, block| @@ -109,6 +116,5 @@ module Sinatra halt_response("Content-Type should be 'application/json'", 415) if request.media_type.nil? or request.media_type != 'application/json' end - end end