505 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			505 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| 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")
 | |
|             json Devops::API2_0::Handler::Server.new(request).servers
 | |
|           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).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 |provider|
 | |
|             check_privileges("server", "r")
 | |
|             json Devops::API2_0::Handler::Server.new(request).provider_servers(provider)
 | |
|           end
 | |
| 
 | |
|           app.get_with_headers "/servers/provider/:provider/:account", :headers => [:accept] do |provider, account|
 | |
|             check_privileges("server", "r")
 | |
|             json Devops::API2_0::Handler::Server.new(request).provider_servers_with_account(provider, account)
 | |
|           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).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")
 | |
|             json Devops::API2_0::Handler::Server.new(request).delete(id)
 | |
|           }
 | |
|           app.multi_routes "/server/:id", {:headers => [:accept, :content_type]}, hash
 | |
| 
 | |
|           # Run deploy command on reserved server
 | |
|           #
 | |
|           # * *Request*
 | |
|           #   - method : POST
 | |
|           #   - headers :
 | |
|           #     - Content-Type: application/json
 | |
|           #   - body :
 | |
|           #     {
 | |
|           #       "names": [],  -> array of servers names to run chef-client
 | |
|           #       "tags": [],   -> array of tags to apply on each server before running chef-client
 | |
|           #       "build_number": "", -> string, build number to deploy
 | |
|           #       "run_list": [],   -> array of strings to set run_list for chef-client
 | |
|           #     }
 | |
|           #
 | |
|           # * *Returns* : text stream
 | |
|           app.post_with_headers "/server/:node_name/deploy", :headers => [:content_type, :accept] do |node_name|
 | |
|             check_privileges("server", "x")
 | |
| 
 | |
|             if request["HTTP_X_STREAM"]
 | |
|               stream() do |out|
 | |
|                 status = []
 | |
|                 begin
 | |
|                   status = Devops::API2_0::Handler::Server.new(request).deploy_stream(node_name, out)
 | |
|                   out << create_status(status)
 | |
|                 rescue DeployInfoError => e
 | |
|                   msg = "Can not get deploy info: " + e.message
 | |
|                   DevopsLogger.logger.error "msg:\n#{e.backtrace.join('\n')}"
 | |
|                   out.puts msg
 | |
|                 rescue IOError => e
 | |
|                   logger.error e.message
 | |
|                   break
 | |
|                 end
 | |
|               end # stream
 | |
|             else
 | |
|               files = begin
 | |
|                 Devops::API2_0::Handler::Server.new(request).deploy(node_name)
 | |
|               rescue DeployInfoError => e
 | |
|                 msg = "Can not get deploy info: " + e.message
 | |
|                 DevopsLogger.logger.error "#{msg}:\n#{e.backtrace.join("\n")}"
 | |
|                 out << "\nError - "
 | |
|                 out.puts msg
 | |
|               end
 | |
|               sleep 1
 | |
|               json files
 | |
|             end
 | |
|           end
 | |
| 
 | |
|           # Create devops server
 | |
|           #
 | |
|           # * *Request*
 | |
|           #   - method : POST
 | |
|           #   - headers :
 | |
|           #     - X-Stream: true -> return output in text stream
 | |
|           #     - 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
 | |
|           #       "private_ip": null         -> should be string like "172.31.31.203" if present
 | |
|           #       "project_info": {
 | |
|           #         "deployers": ['user1']   -> currently it's used only in sandbox projects
 | |
|           #       }
 | |
|           #     }
 | |
|           #
 | |
|           # * *Returns* : text stream
 | |
|           app.post_with_headers "/server", :headers => [:accept, :content_type] do
 | |
|             check_privileges("server", "w")
 | |
|             handler = Devops::API2_0::Handler::Server.new(request)
 | |
|             if request["X-Stream"] or request["HTTP_X_STREAM"]
 | |
|               stream() do |out|
 | |
|                 begin
 | |
|                   status = handler.create_server_stream out
 | |
|                   out << create_status(status)
 | |
|                 rescue IOError => e
 | |
|                   logger.error e.message
 | |
|                 end
 | |
|               end
 | |
|             else
 | |
|               json handler.create_server
 | |
|             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")
 | |
|             info = Devops::API2_0::Handler::Server.new(request).pause_server(node_name)
 | |
|             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")
 | |
|             info = Devops::API2_0::Handler::Server.new(request).unpause_server(node_name)
 | |
|             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")
 | |
|             Devops::API2_0::Handler::Server.new(request).reserve_server(node_name)
 | |
|             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")
 | |
|             Devops::API2_0::Handler::Server.new(request).unreserve_server(node_name)
 | |
|             create_response("Server '#{node_name}' has been unreserved")
 | |
|           end
 | |
| 
 | |
|           # Bootstrap devops server
 | |
|           #
 | |
|           # * *Request*
 | |
|           #   - method : POST
 | |
|           #   - headers :
 | |
|           #     - X-Stream: true -> return output in text stream
 | |
|           #     - 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")
 | |
| 
 | |
|             handler = Devops::API2_0::Handler::Server.new(request)
 | |
|             if request["X-Stream"]
 | |
|               stream() do |out|
 | |
|                 begin
 | |
|                   status = handler.bootstrap_server_stream out
 | |
|                   out << create_status(status)
 | |
|                 rescue IOError => e
 | |
|                   logger.error e.message
 | |
|                 end
 | |
|               end
 | |
|             else
 | |
|               json handler.bootstrap_server()
 | |
|             end
 | |
|           end
 | |
| 
 | |
|           # Unbootstrap 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
 | |
|           app.post_with_headers "/server/:id/unbootstrap", :headers => [:accept, :content_type] do |id|
 | |
|             check_privileges("server", "w")
 | |
|             info = Devops::API2_0::Handler::Server.new(request).unbootstrap_server(id)
 | |
|             create_response("Unbootstrap", info)
 | |
|           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")
 | |
|             info = Devops::API2_0::Handler::Server.new(request).add_server()
 | |
|             create_response(info)
 | |
|           end
 | |
| 
 | |
| 
 | |
|           # Add list of external servers to devops and bootstrap them
 | |
|           #
 | |
|           # * *Request*
 | |
|           #   - method : POST
 | |
|           #   - headers :
 | |
|           #     - Accept: application/json
 | |
|           #     - Content-Type: application/json
 | |
|           #   - body :
 | |
|           #     {
 | |
|           #       "project": "project name", -> required
 | |
|           #       "deploy_env": "env",       -> required
 | |
|           #       "key": "ssh key",          -> required
 | |
|           #       "remote_user": "ssh user", -> required
 | |
|           #       "ips_with_names": multiline string like, required
 | |
|           #           127.0.0.1:node1
 | |
|           #           127.0.0.2:node2
 | |
|           #       "private_ip": "ip",         -> required
 | |
|           #       "public_ip": "ip"
 | |
|           #     }
 | |
|           #
 | |
|           # * *Returns* :
 | |
|           #   ["report1", "report2"]
 | |
|           app.post_with_headers "/server/add_and_bootstrap_servers", :headers => [:accept, :content_type] do
 | |
|             check_privileges("server", "w")
 | |
|             json Devops::API2_0::Handler::Server.new(request).add_and_bootstrap_servers()
 | |
|           end
 | |
| 
 | |
|           hash = {}
 | |
|           # Add instance tags
 | |
|           #
 | |
|           # * *Request*
 | |
|           #   - method : PUT
 | |
|           #   - headers :
 | |
|           #     - Content-Type: application/json
 | |
|           #   - body :
 | |
|           #     {
 | |
|           #       "tags": {"tag name": "tag value"}
 | |
|           #       "key": "instance", -> search server by instance_id rather then chef_node_name
 | |
|           #     }
 | |
|           #
 | |
|           # * *Returns* :
 | |
|           #   200 - Added
 | |
|           hash["PUT"] = lambda {|id|
 | |
|             check_privileges("server", "w")
 | |
|             Devops::API2_0::Handler::Server.new(request).set_tags(id)
 | |
|             create_response("Added")
 | |
|           }
 | |
| 
 | |
|           # Delete instance tags
 | |
|           #
 | |
|           # * *Request*
 | |
|           #   - method : DELETE
 | |
|           #   - headers :
 | |
|           #     - Content-Type: application/json
 | |
|           #   - body :
 | |
|           #     {
 | |
|           #       "tags": {"tag name": "tag value"}
 | |
|           #       "key": "instance", -> search server by instance_id rather then chef_node_name
 | |
|           #     }
 | |
|           #
 | |
|           # * *Returns* :
 | |
|           #   200 - Deleted
 | |
|           hash["DELETE"] = lambda {|id|
 | |
|             check_privileges("server", "w")
 | |
|             Devops::API2_0::Handler::Server.new(request).unset_tags(id)
 | |
|             create_response("Deleted")
 | |
|           }
 | |
|           app.multi_routes "/server/:id/tags", {:headers => [:content_type]}, hash
 | |
| 
 | |
|           # Set run_list to server
 | |
|           #
 | |
|           # * *Request*
 | |
|           #   - method : PATCH
 | |
|           #   - headers :
 | |
|           #     - Accept: application/json
 | |
|           #     - Content-Type: application/json
 | |
|           #   - body :
 | |
|           #     {
 | |
|           #       "run_list": [
 | |
|           #         "role[role_1]",
 | |
|           #         "recipe[recipe_1]"
 | |
|           #       ],
 | |
|           #       "key": "instance", -> search server by instance_id rather then chef_node_name
 | |
|           #     }
 | |
|           #
 | |
|           # * *Returns* :
 | |
|           #   200 - Updated
 | |
|           app.put_with_headers "/server/:id/run_list", :headers => [:accept, :content_type] do |node_name|
 | |
|             check_privileges("server", "w")
 | |
|             Devops::API2_0::Handler::Server.new(request).set_run_list(node_name)
 | |
|             create_response("Run list has been changed")
 | |
|           end
 | |
| 
 | |
| 
 | |
|           # Delete list of servers
 | |
|           #
 | |
|           # * *Request*
 | |
|           #   - method : POST
 | |
|           #   - headers :
 | |
|           #     - Accept: application/json
 | |
|           #     - Content-Type: application/json
 | |
|           #   - body :
 | |
|           #     {
 | |
|           #       "servers_ids": [ "server1", "server2"]
 | |
|           #     }
 | |
|           #
 | |
|           # * *Returns* :
 | |
|           #   {
 | |
|           #     "server1": "report_1",
 | |
|           #     "server2": "report_2"
 | |
|           #    }
 | |
|           app.post_with_headers "/server/delete_list", :headers => [:accept, :content_type] do
 | |
|             check_privileges("server", "w")
 | |
|             json Devops::API2_0::Handler::Server.new(request).delete_list
 | |
|           end
 | |
| 
 | |
|           puts "Server routes initialized"
 | |
|         end
 | |
| 
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 | 
