require "json" module Devops module API2_0 module Routes module ServerRoutes def self.registered(app) # Get devops servers list # # * *Request* # - method : GET # - headers : # - Accept: application/json # - params : # - fields - show server fields, available values: project, deploy_env, provider, remote_user, private_ip, public_ip, created_at, created_by, static, key, reserved_by # # * *Returns* : # [ # { # "id": "instance id", # "chef_node_name": "chef name" # } # ] app.get_with_headers "/servers", :headers => [:accept] do check_privileges("server", "r") fields = [] if params.key?("fields") and params["fields"].is_a?(Array) Devops::Model::Server.fields.each do |k| fields.push k if params["fields"].include?(k) end end reserved = (params.key?("reserved") ? true : nil) json Devops::API2_0::Handler::Server.new(request, params).servers(fields, reserved) end # Get chef nodes list # # * *Request* # - method : GET # - headers : # - Accept: application/json # # * *Returns* : # [ # { # "chef_node_name": "chef name" # } # ] app.get_with_headers "/servers/chef", :headers => [:accept] do check_privileges("server", "r") json Devops::API2_0::Handler::Server.new(request, params).chef_servers end # Get provider servers list # # * *Request* # - method : GET # - headers : # - Accept: application/json # # * *Returns* : # -ec2 # [ # { # "state": "running", # "name": "name", # "image": "ami-83e4bcea", # "flavor": "m1.small", # "keypair": "ssh key", # "instance_id": "i-8441bfd4", # "dns_name": "ec2-204-236-199-49.compute-1.amazonaws.com", # "zone": "us-east-1d", # "private_ip": "10.215.217.210", # "public_ip": "204.236.199.49", # "launched_at": "2014-04-25 07:56:33 UTC" # } # ] # -openstack # [ # { # "state": "ACTIVE", # "name": "name", # "image": "image id", # "flavor": null, # "keypair": "ssh key", # "instance_id": "instance id", # "private_ip": "172.17.0.1" # } # ] app.get_with_headers "/servers/:provider", :headers => [:accept] do check_privileges("server", "r") json Devops::API2_0::Handler::Server.new(request, params).provider_servers(params[:provider]) end # Get server info by :name # # * *Request* # - method : GET # - headers : # - Accept: application/json # - parameters: # key=instance -> search server by instance_id rather then chef_node_name # # * *Returns* : # [ # { # "chef_node_name": "chef name" # } # ] hash = {} hash["GET"] = lambda {|id| check_privileges("server", "r") json Devops::API2_0::Handler::Server.new(request, params).server(id).to_hash } # Delete devops server # # * *Request* # - method : DELETE # - headers : # - Accept: application/json # - Content-Type: application/json # - body : # { # "key": "instance", -> search server by instance_id rather then chef_node_name # } # # * *Returns* : # 200 - Deleted hash["DELETE"] = lambda {|id| check_privileges("server", "w") body = create_object_from_json_body(Hash, true) key = (body.nil? ? nil : body["key"]) info, r = Devops::API2_0::Handler::Server.new(request, params).delete(id, key) create_response(info, r) } app.multi_routes "/server/:id", {:headers => [:accept, :content_type]}, hash # Create devops server # # * *Request* # - method : POST # - headers : # - Accept: application/json # - Content-Type: application/json # - body : # { # "project": "project name", -> mandatory parameter # "deploy_env": "env", -> mandatory parameter # "name": "server_name", -> if null, name will be generated # "without_bootstrap": null, -> do not install chef on instance if true # "force": null, -> do not delete server on error # "groups": [], -> specify special security groups, overrides value from project env # "key": "ssh key", -> specify ssh key for server, overrides value from project env # "trace": true -> return output in stream # } # # * *Returns* : text stream app.post_with_headers "/server", :headers => [:content_type] do check_privileges("server", "w") body = create_object_from_json_body project_name = check_string(body["project"], "Parameter 'project' must be a not empty string") env_name = check_string(body["deploy_env"], "Parameter 'deploy_env' must be a not empty string") server_name = check_string(body["name"], "Parameter 'name' should be null or not empty string", true) without_bootstrap = body["without_bootstrap"] force = body["force"] halt_response("Parameter 'without_bootstrap' should be a null or true") unless without_bootstrap.nil? or without_bootstrap == true halt_response("Parameter 'force' should be a null or true") unless force.nil? or force == true groups = check_array(body["groups"], "Parameter 'groups' should be null or not empty array of string", String, true) key_name = check_string(body["key"], "Parameter 'key' should be null or not empty string", true) handler = Devops::API2_0::Handler::Server.new(request, params) if body.key?("trace") stream() do |out| begin status = handler.create_server_stream out, body out << create_status(status) rescue IOError => e logger.error e.message end end else json handler.create_server body end end # Pause devops server by name # # * *Request* # - method : POST # - headers : # - Accept: application/json # - Content-Type: application/json # - body : # { # "key": "instance", -> search server by instance_id rather then chef_node_name # } # # * *Returns* : # 200 - Paused app.post_with_headers "/server/:node_name/pause", :headers => [:accept, :content_type] do |node_name| check_privileges("server", "w") body = create_object_from_json_body(Hash, true) key = (body.nil? ? nil : body["key"]) info = Devops::API2_0::Handler::Server.new(request, params).pause_server(node_name, key) create_response(info) end # Unpause devops server by name # # * *Request* # - method : POST # - headers : # - Accept: application/json # - Content-Type: application/json # - body : # { # "key": "instance", -> search server by instance_id rather then chef_node_name # } # # * *Returns* : # 200 - Unpaused app.post_with_headers "/server/:node_name/unpause", :headers => [:accept, :content_type] do |node_name| check_privileges("server", "w") body = create_object_from_json_body(Hash, true) key = (body.nil? ? nil : body["key"]) info = Devops::API2_0::Handler::Server.new(request, params).unpause_server(node_name, key) create_response(info) end # Reserve devops server # # * *Request* # - method : POST # - headers : # - Accept: application/json # - Content-Type: application/json # - body : # { # "key": "instance", -> search server by instance_id rather then chef_node_name # } # # * *Returns* : # 200 - Reserved app.post_with_headers "/server/:node_name/reserve", :headers => [:accept, :content_type] do |node_name| check_privileges("server", "w") body = create_object_from_json_body(Hash, true) key = (body.nil? ? nil : body["key"]) Devops::API2_0::Handler::Server.new(request, params).reserve_server(node_name, key) create_response("Server '#{node_name}' has been reserved") end # Unreserve devops server # # * *Request* # - method : POST # - headers : # - Accept: application/json # - Content-Type: application/json # - body : # { # "key": "instance", -> search server by instance_id rather then chef_node_name # } # # * *Returns* : # 200 - Unreserved app.post_with_headers "/server/:node_name/unreserve", :headers => [:accept, :content_type] do |node_name| check_privileges("server", "w") body = create_object_from_json_body(Hash, true) key = (body.nil? ? nil : body["key"]) Devops::API2_0::Handler::Server.new(request, params).unreserve_server(node_name, key) create_response("Server '#{node_name}' has been unreserved") end # Bootstrap devops server # # * *Request* # - method : POST # - headers : # - Accept: application/json # - Content-Type: application/json # - body : # { # "instance_id": "instance id", -> mandatory parameter # "name": "server_name", -> if null, name will be generated # "run_list": [], -> specify list of roles and recipes # "bootstrap_template": "template" -> specify ssh key for server, overrides value from project env # } # # * *Returns* : text stream app.post_with_headers "/server/bootstrap", :headers => [:accept, :content_type] do 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) rl = check_array(body["run_list"], "Parameter 'run_list' should be a not empty array of string", String, true) unless rl.nil? validator = Validators::Helpers::RunList.new(rl) halt_response(validator.message) unless validator.valid? end t = check_string(body["bootstrap_template"], "Parameter 'bootstrap_template' should be a not empty string", true) handler = Devops::API2_0::Handler::Server.new(request, params) if body.key?("trace") stream() do |out| begin status = handler.bootstrap_server_stream out, body out << create_status(status) rescue IOError => e logger.error e.message end end else handler.bootstrap_server(body) end end # Add external server to devops # # * *Request* # - method : POST # - headers : # - Accept: application/json # - Content-Type: application/json # - body : # { # "project": "project name", -> mandatory parameter # "deploy_env": "env", -> mandatory parameter # "key": "ssh key", -> mandatory parameter # "remote_user": "ssh user", -> mandatory parameter # "private_ip": "ip", -> mandatory parameter # "public_ip": "ip" # } # # * *Returns* : # 200 - Added app.post_with_headers "/server/add", :headers => [:accept, :content_type] do 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") key = check_string(body["key"], "Parameter 'key' must be a not empty string") remote_user = check_string(body["remote_user"], "Parameter 'remote_user' must be a not empty string") private_ip = check_string(body["private_ip"], "Parameter 'private_ip' must be a not empty string") public_ip = check_string(body["public_ip"], "Parameter 'public_ip' should be a not empty string", true) info = Devops::API2_0::Handler::Server.new(request, params).add_server(body) create_response(info) end puts "Server routes initialized" end end end end end