sinatra modules
This commit is contained in:
parent
cbf48145cd
commit
79e2811e0c
@ -20,11 +20,6 @@ else
|
|||||||
end
|
end
|
||||||
|
|
||||||
config[:devops_dir] = File.join(ENV["HOME"], ".devops") if config[:devops_dir].nil?
|
config[:devops_dir] = File.join(ENV["HOME"], ".devops") if config[:devops_dir].nil?
|
||||||
puts "Devops home: #{config[:devops_dir]}"
|
|
||||||
unless File.exists?(config[:devops_dir])
|
|
||||||
FileUtils.mkdir_p config[:devops_dir]
|
|
||||||
puts "Directory '#{config[:devops_dir]}' has been created"
|
|
||||||
end
|
|
||||||
|
|
||||||
config[:report_dir_v2] = File.expand_path(File.join(config[:devops_dir], "report", "v2")) unless config[:report_dir_v2]
|
config[:report_dir_v2] = File.expand_path(File.join(config[:devops_dir], "report", "v2")) unless config[:report_dir_v2]
|
||||||
[
|
[
|
||||||
|
|||||||
@ -21,13 +21,32 @@ require "routes/v2.0/user"
|
|||||||
class DevopsService < Sinatra::Base
|
class DevopsService < Sinatra::Base
|
||||||
|
|
||||||
helpers Sinatra::Streaming
|
helpers Sinatra::Streaming
|
||||||
helpers Sinatra::Version2_0::Helpers
|
helpers Devops::Version2_0::Helpers
|
||||||
|
|
||||||
register Sinatra::Version2_0::Core::ProviderRoutes
|
register Devops::Version2_0::Core::ProviderRoutes
|
||||||
register Sinatra::Version2_0::Core::UserRoutes
|
register Devops::Version2_0::Core::BootstrapTemplatesRoutes
|
||||||
|
register Devops::Version2_0::Core::UserRoutes
|
||||||
|
register Devops::Version2_0::Core::FilterRoutes
|
||||||
|
register Devops::Version2_0::Core::FlavorRoutes
|
||||||
|
register Devops::Version2_0::Core::GroupRoutes
|
||||||
|
register Devops::Version2_0::Core::ImageRoutes
|
||||||
|
register Devops::Version2_0::Core::KeyRoutes
|
||||||
|
register Devops::Version2_0::Core::NetworkRoutes
|
||||||
|
register Devops::Version2_0::Core::ProjectRoutes
|
||||||
|
register Devops::Version2_0::Core::ScriptRoutes
|
||||||
|
register Devops::Version2_0::Core::ServerRoutes
|
||||||
|
register Devops::Version2_0::Core::StatusRoutes
|
||||||
|
register Devops::Version2_0::Core::TagRoutes
|
||||||
|
|
||||||
def initialize config
|
def initialize config
|
||||||
super()
|
super()
|
||||||
|
puts "Devops home: #{config[:devops_dir]}"
|
||||||
|
unless File.exists?(config[:devops_dir])
|
||||||
|
FileUtils.mkdir_p config[:devops_dir]
|
||||||
|
puts "Directory '#{config[:devops_dir]}' has been created"
|
||||||
|
end
|
||||||
|
self.class.set :devops_home, config[:devops_dir]
|
||||||
|
|
||||||
self.class.set :config, config
|
self.class.set :config, config
|
||||||
@@config = config
|
@@config = config
|
||||||
root = File.dirname(__FILE__)
|
root = File.dirname(__FILE__)
|
||||||
@ -57,7 +76,7 @@ class DevopsService < Sinatra::Base
|
|||||||
|
|
||||||
use Rack::Auth::Basic do |username, password|
|
use Rack::Auth::Basic do |username, password|
|
||||||
begin
|
begin
|
||||||
mongo.user_auth(username, password)
|
settings.mongo.user_auth(username, password)
|
||||||
true
|
true
|
||||||
rescue RecordNotFound => e
|
rescue RecordNotFound => e
|
||||||
false
|
false
|
||||||
@ -70,6 +89,7 @@ class DevopsService < Sinatra::Base
|
|||||||
disable :dump_errors
|
disable :dump_errors
|
||||||
disable :show_exceptions
|
disable :show_exceptions
|
||||||
set :logging, Logger::INFO
|
set :logging, Logger::INFO
|
||||||
|
puts "TODO2"
|
||||||
end
|
end
|
||||||
|
|
||||||
configure :development do
|
configure :development do
|
||||||
@ -77,6 +97,7 @@ class DevopsService < Sinatra::Base
|
|||||||
disable :raise_errors
|
disable :raise_errors
|
||||||
# disable :dump_errors
|
# disable :dump_errors
|
||||||
set :show_exceptions, :after_handler
|
set :show_exceptions, :after_handler
|
||||||
|
puts "TODO1"
|
||||||
end
|
end
|
||||||
|
|
||||||
not_found do
|
not_found do
|
||||||
|
|||||||
@ -2,10 +2,9 @@ require "json"
|
|||||||
require 'sinatra/base'
|
require 'sinatra/base'
|
||||||
require "sinatra/json"
|
require "sinatra/json"
|
||||||
|
|
||||||
|
|
||||||
require "providers/provider_factory"
|
require "providers/provider_factory"
|
||||||
|
|
||||||
module Sinatra
|
module Devops
|
||||||
module Version2_0
|
module Version2_0
|
||||||
module Helpers
|
module Helpers
|
||||||
|
|
||||||
|
|||||||
@ -1,35 +1,37 @@
|
|||||||
require "json"
|
require "json"
|
||||||
require "routes/v2.0/base_routes"
|
|
||||||
require "providers/provider_factory"
|
require "providers/provider_factory"
|
||||||
require "commands/bootstrap_templates"
|
require "commands/bootstrap_templates"
|
||||||
|
|
||||||
module Version2_0
|
module Devops
|
||||||
class BootstrapTemplatesRoutes < BaseRoutes
|
module Version2_0
|
||||||
|
module Core
|
||||||
|
module BootstrapTemplatesRoutes
|
||||||
|
|
||||||
include BootstrapTemplatesCommands
|
extend BootstrapTemplatesCommands
|
||||||
|
|
||||||
def initialize wrapper
|
def self.registered(app)
|
||||||
super wrapper
|
|
||||||
puts "Bootstrap templates routes initialized"
|
# Get list of available bootstrap templates
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : GET
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
#
|
||||||
|
# * *Returns* : array of strings
|
||||||
|
# [
|
||||||
|
# "omnibus"
|
||||||
|
# ]
|
||||||
|
app.get "/templates" do
|
||||||
|
check_headers :accept
|
||||||
|
check_privileges("templates", "r")
|
||||||
|
json BootstrapTemplatesRoutes.get_templates
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Bootstrap templates routes initialized"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get list of available bootstrap templates
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : GET
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* : array of strings
|
|
||||||
# [
|
|
||||||
# "omnibus"
|
|
||||||
# ]
|
|
||||||
get "/templates" do
|
|
||||||
check_headers :accept
|
|
||||||
check_privileges("templates", "r")
|
|
||||||
json get_templates
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,84 +1,87 @@
|
|||||||
require "routes/v2.0/base_routes"
|
|
||||||
|
|
||||||
module Version2_0
|
module Devops
|
||||||
class FilterRoutes < BaseRoutes
|
module Version2_0
|
||||||
|
module Core
|
||||||
|
module FilterRoutes
|
||||||
|
|
||||||
def initialize wrapper
|
def self.registered(app)
|
||||||
super wrapper
|
|
||||||
puts "Filter routes initialized"
|
app.before "/filter/:provider/image" do
|
||||||
|
check_headers :accept, :content_type
|
||||||
|
check_privileges("filter", "w")
|
||||||
|
check_provider(params[:provider])
|
||||||
|
@images = create_object_from_json_body(Array)
|
||||||
|
halt_response("Request body should not be an empty array") if @images.empty?
|
||||||
|
check_array(@images, "Request body should contains an array with strings")
|
||||||
|
end
|
||||||
|
|
||||||
|
app.after "/filter/:provider/image" do
|
||||||
|
statistic
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get list of images filters for :provider
|
||||||
|
#
|
||||||
|
# Devops can works with images from filters list only
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : GET
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
#
|
||||||
|
# * *Returns* : array of strings
|
||||||
|
# - ec2:
|
||||||
|
# [
|
||||||
|
# "ami-83e4bcea"
|
||||||
|
# ]
|
||||||
|
# - openstack:
|
||||||
|
# [
|
||||||
|
# "36dc7618-4178-4e29-be43-286fbfe90f50"
|
||||||
|
# ]
|
||||||
|
app.get "/filter/:provider/images" do
|
||||||
|
check_headers :accept
|
||||||
|
check_privileges("filter", "r")
|
||||||
|
check_provider(params[:provider])
|
||||||
|
json settings.mongo.available_images(params[:provider])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add image ids to filter for :provider
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : PUT
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
# - Content-Type: application/json
|
||||||
|
# - body :
|
||||||
|
# [
|
||||||
|
# "image_id"
|
||||||
|
# ] -> array of image ids to add to filter
|
||||||
|
#
|
||||||
|
# * *Returns* : list of images filters for :provider
|
||||||
|
app.put "/filter/:provider/image" do
|
||||||
|
create_response("Updated", {:images => settings.mongo.add_available_images(@images, params[:provider])})
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delete image ids from filter for :provider
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : DELETE
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
# - Content-Type: application/json
|
||||||
|
# - body :
|
||||||
|
# [
|
||||||
|
# "image_id"
|
||||||
|
# ] -> array of image ids to delete from filter
|
||||||
|
#
|
||||||
|
# * *Returns* : list of images filters for :provider
|
||||||
|
app.delete "/filter/:provider/image" do
|
||||||
|
create_response("Deleted", {:images => settings.mongo.delete_available_images(@images, params[:provider])})
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Filter routes initialized"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
before "/filter/:provider/image" do
|
|
||||||
check_headers :accept, :content_type
|
|
||||||
check_privileges("filter", "w")
|
|
||||||
check_provider(params[:provider])
|
|
||||||
@images = create_object_from_json_body(Array)
|
|
||||||
halt_response("Request body should not be an empty array") if @images.empty?
|
|
||||||
check_array(@images, "Request body should contains an array with strings")
|
|
||||||
end
|
|
||||||
|
|
||||||
after "/filter/:provider/image" do
|
|
||||||
statistic
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get list of images filters for :provider
|
|
||||||
#
|
|
||||||
# Devops can works with images from filters list only
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : GET
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* : array of strings
|
|
||||||
# - ec2:
|
|
||||||
# [
|
|
||||||
# "ami-83e4bcea"
|
|
||||||
# ]
|
|
||||||
# - openstack:
|
|
||||||
# [
|
|
||||||
# "36dc7618-4178-4e29-be43-286fbfe90f50"
|
|
||||||
# ]
|
|
||||||
get "/filter/:provider/images" do
|
|
||||||
check_headers :accept
|
|
||||||
check_privileges("filter", "r")
|
|
||||||
check_provider(params[:provider])
|
|
||||||
json BaseRoutes.mongo.available_images(params[:provider])
|
|
||||||
end
|
|
||||||
|
|
||||||
# Add image ids to filter for :provider
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : PUT
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
# - Content-Type: application/json
|
|
||||||
# - body :
|
|
||||||
# [
|
|
||||||
# "image_id"
|
|
||||||
# ] -> array of image ids to add to filter
|
|
||||||
#
|
|
||||||
# * *Returns* : list of images filters for :provider
|
|
||||||
put "/filter/:provider/image" do
|
|
||||||
create_response("Updated", {:images => BaseRoutes.mongo.add_available_images(@images, params[:provider])})
|
|
||||||
end
|
|
||||||
|
|
||||||
# Delete image ids from filter for :provider
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : DELETE
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
# - Content-Type: application/json
|
|
||||||
# - body :
|
|
||||||
# [
|
|
||||||
# "image_id"
|
|
||||||
# ] -> array of image ids to delete from filter
|
|
||||||
#
|
|
||||||
# * *Returns* : list of images filters for :provider
|
|
||||||
delete "/filter/:provider/image" do
|
|
||||||
create_response("Deleted", {:images => BaseRoutes.mongo.delete_available_images(@images, params[:provider])})
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,49 +1,52 @@
|
|||||||
require "json"
|
require "json"
|
||||||
require "routes/v2.0/base_routes"
|
|
||||||
require "providers/provider_factory"
|
require "providers/provider_factory"
|
||||||
|
|
||||||
module Version2_0
|
module Devops
|
||||||
class FlavorRoutes < BaseRoutes
|
module Version2_0
|
||||||
|
module Core
|
||||||
|
module FlavorRoutes
|
||||||
|
|
||||||
def initialize wrapper
|
def self.registered(app)
|
||||||
super wrapper
|
|
||||||
puts "Flavor routes initialized"
|
# Get list of flavors for :provider
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : GET
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
#
|
||||||
|
# * *Returns* : array of objects
|
||||||
|
# - ec2:
|
||||||
|
# [
|
||||||
|
# {
|
||||||
|
# "id": "t1.micro",
|
||||||
|
# "cores": 2,
|
||||||
|
# "disk": 0,
|
||||||
|
# "name": "Micro Instance",
|
||||||
|
# "ram": 613
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
# - openstack:
|
||||||
|
# [
|
||||||
|
# {
|
||||||
|
# "id": "m1.small",
|
||||||
|
# "v_cpus": 1,
|
||||||
|
# "ram": 2048,
|
||||||
|
# "disk": 20
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
app.get "/flavors/:provider" do
|
||||||
|
check_headers :accept
|
||||||
|
check_privileges("flavor", "r")
|
||||||
|
check_provider(params[:provider])
|
||||||
|
p = ::Provider::ProviderFactory.get params[:provider]
|
||||||
|
json p.flavors
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Flavor routes initialized"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get list of flavors for :provider
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : GET
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* : array of objects
|
|
||||||
# - ec2:
|
|
||||||
# [
|
|
||||||
# {
|
|
||||||
# "id": "t1.micro",
|
|
||||||
# "cores": 2,
|
|
||||||
# "disk": 0,
|
|
||||||
# "name": "Micro Instance",
|
|
||||||
# "ram": 613
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
# - openstack:
|
|
||||||
# [
|
|
||||||
# {
|
|
||||||
# "id": "m1.small",
|
|
||||||
# "v_cpus": 1,
|
|
||||||
# "ram": 2048,
|
|
||||||
# "disk": 20
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
get "/flavors/:provider" do
|
|
||||||
check_headers :accept
|
|
||||||
check_privileges("flavor", "r")
|
|
||||||
check_provider(params[:provider])
|
|
||||||
p = ::Provider::ProviderFactory.get params[:provider]
|
|
||||||
json p.flavors
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,61 +1,63 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
require "json"
|
require "json"
|
||||||
require "routes/v2.0/base_routes"
|
|
||||||
require "providers/provider_factory"
|
require "providers/provider_factory"
|
||||||
|
|
||||||
module Version2_0
|
module Devops
|
||||||
class GroupRoutes < BaseRoutes
|
module Version2_0
|
||||||
|
module Core
|
||||||
|
module GroupRoutes
|
||||||
|
|
||||||
def initialize wrapper
|
def self.registered(app)
|
||||||
super wrapper
|
# Get security groups for :provider
|
||||||
puts "Group routes initialized"
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : GET
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
#
|
||||||
|
# * *Returns* :
|
||||||
|
# - ec2:
|
||||||
|
# {
|
||||||
|
# "default": {
|
||||||
|
# "description": "default group",
|
||||||
|
# "id": "sg-565cf93f",
|
||||||
|
# "rules": [
|
||||||
|
# {
|
||||||
|
# "protocol": "tcp",
|
||||||
|
# "from": 22,
|
||||||
|
# "to": 22,
|
||||||
|
# "cidr": "0.0.0.0/0"
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# - openstack:
|
||||||
|
# {
|
||||||
|
# "default": {
|
||||||
|
# "description": "default",
|
||||||
|
# "rules": [
|
||||||
|
# {
|
||||||
|
# "protocol": null,
|
||||||
|
# "from": null,
|
||||||
|
# "to": null,
|
||||||
|
# "cidr": null
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# TODO: vpc support for ec2
|
||||||
|
app.get "/groups/:provider" do
|
||||||
|
check_headers :accept
|
||||||
|
check_privileges("group", "r")
|
||||||
|
check_provider(params[:provider])
|
||||||
|
p = ::Provider::ProviderFactory.get params[:provider]
|
||||||
|
json p.groups(params)
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Group routes initialized"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get security groups for :provider
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : GET
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* :
|
|
||||||
# - ec2:
|
|
||||||
# {
|
|
||||||
# "default": {
|
|
||||||
# "description": "default group",
|
|
||||||
# "id": "sg-565cf93f",
|
|
||||||
# "rules": [
|
|
||||||
# {
|
|
||||||
# "protocol": "tcp",
|
|
||||||
# "from": 22,
|
|
||||||
# "to": 22,
|
|
||||||
# "cidr": "0.0.0.0/0"
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# - openstack:
|
|
||||||
# {
|
|
||||||
# "default": {
|
|
||||||
# "description": "default",
|
|
||||||
# "rules": [
|
|
||||||
# {
|
|
||||||
# "protocol": null,
|
|
||||||
# "from": null,
|
|
||||||
# "to": null,
|
|
||||||
# "cidr": null
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# TODO: vpc support for ec2
|
|
||||||
get "/groups/:provider" do
|
|
||||||
check_headers :accept
|
|
||||||
check_privileges("group", "r")
|
|
||||||
check_provider(params[:provider])
|
|
||||||
p = ::Provider::ProviderFactory.get params[:provider]
|
|
||||||
json p.groups(params)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,178 +1,180 @@
|
|||||||
require "providers/provider_factory"
|
require "providers/provider_factory"
|
||||||
require "routes/v2.0/base_routes"
|
|
||||||
require "commands/image"
|
require "commands/image"
|
||||||
|
|
||||||
module Version2_0
|
module Devops
|
||||||
class ImageRoutes < BaseRoutes
|
module Version2_0
|
||||||
|
module Core
|
||||||
|
module ImageRoutes
|
||||||
|
|
||||||
include ImageCommands
|
extend ImageCommands
|
||||||
|
|
||||||
def initialize wrapper
|
def self.registered(app)
|
||||||
super wrapper
|
app.after %r{\A/image(/[\w]+)?\z} do
|
||||||
puts "Image routes initialized"
|
statistic
|
||||||
end
|
end
|
||||||
|
|
||||||
after %r{\A/image(/[\w]+)?\z} do
|
# Get devops images list
|
||||||
statistic
|
#
|
||||||
end
|
# * *Request*
|
||||||
|
# - method : GET
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
# - parameters:
|
||||||
|
# - provider=ec2|openstack -> return images for provider
|
||||||
|
#
|
||||||
|
# * *Returns* :
|
||||||
|
# [
|
||||||
|
# {
|
||||||
|
# "provider": "openstack",
|
||||||
|
# "name": "centos-6.4-x86_64",
|
||||||
|
# "remote_user": "root",
|
||||||
|
# "bootstrap_template": null,
|
||||||
|
# "id": "36dc7618-4178-4e29-be43-286fbfe90f50"
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
app.get "/images" do
|
||||||
|
check_headers :accept
|
||||||
|
check_privileges("image", "r")
|
||||||
|
check_provider(params[:provider]) if params[:provider]
|
||||||
|
images = settings.mongo.images(params[:provider])
|
||||||
|
json(images.map {|i| i.to_hash})
|
||||||
|
end
|
||||||
|
|
||||||
# Get devops images list
|
# Get raw images for :provider
|
||||||
#
|
#
|
||||||
# * *Request*
|
# * *Request*
|
||||||
# - method : GET
|
# - method : GET
|
||||||
# - headers :
|
# - headers :
|
||||||
# - Accept: application/json
|
# - Accept: application/json
|
||||||
# - parameters:
|
#
|
||||||
# - provider=ec2|openstack -> return images for provider
|
# * *Returns* :
|
||||||
#
|
# - ec2
|
||||||
# * *Returns* :
|
# [
|
||||||
# [
|
# {
|
||||||
# {
|
# "id": "ami-83e4bcea",
|
||||||
# "provider": "openstack",
|
# "name": "amzn-ami-pv-2013.09.1.x86_64-ebs",
|
||||||
# "name": "centos-6.4-x86_64",
|
# "status": "available"
|
||||||
# "remote_user": "root",
|
# }
|
||||||
# "bootstrap_template": null,
|
# ]
|
||||||
# "id": "36dc7618-4178-4e29-be43-286fbfe90f50"
|
# - openstack
|
||||||
# }
|
# [
|
||||||
# ]
|
# {
|
||||||
get "/images" do
|
# "id": "36dc7618-4178-4e29-be43-286fbfe90f50",
|
||||||
check_headers :accept
|
# "name": "centos-6.4-x86_64",
|
||||||
check_privileges("image", "r")
|
# "status": "ACTIVE"
|
||||||
check_provider(params[:provider]) if params[:provider]
|
# }
|
||||||
images = BaseRoutes.mongo.images(params[:provider])
|
# ]
|
||||||
json(images.map {|i| i.to_hash})
|
app.get "/images/provider/:provider" do
|
||||||
end
|
check_headers :accept
|
||||||
|
check_privileges("image", "r")
|
||||||
|
check_provider(params[:provider])
|
||||||
|
json get_images(settings.mongo, params[:provider])
|
||||||
|
end
|
||||||
|
|
||||||
# Get raw images for :provider
|
# Get devops image by id
|
||||||
#
|
#
|
||||||
# * *Request*
|
# * *Request*
|
||||||
# - method : GET
|
# - method : GET
|
||||||
# - headers :
|
# - headers :
|
||||||
# - Accept: application/json
|
# - Accept: application/json
|
||||||
#
|
#
|
||||||
# * *Returns* :
|
# * *Returns* :
|
||||||
# - ec2
|
# {
|
||||||
# [
|
# "provider": "openstack",
|
||||||
# {
|
# "name": "centos-6.4-x86_64",
|
||||||
# "id": "ami-83e4bcea",
|
# "remote_user": "root",
|
||||||
# "name": "amzn-ami-pv-2013.09.1.x86_64-ebs",
|
# "bootstrap_template": null,
|
||||||
# "status": "available"
|
# "id": "36dc7618-4178-4e29-be43-286fbfe90f50"
|
||||||
# }
|
# }
|
||||||
# ]
|
app.get "/image/:image_id" do
|
||||||
# - openstack
|
check_headers :accept
|
||||||
# [
|
check_privileges("image", "r")
|
||||||
# {
|
json settings.mongo.image(params[:image_id])
|
||||||
# "id": "36dc7618-4178-4e29-be43-286fbfe90f50",
|
end
|
||||||
# "name": "centos-6.4-x86_64",
|
|
||||||
# "status": "ACTIVE"
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
get "/images/provider/:provider" do
|
|
||||||
check_headers :accept
|
|
||||||
check_privileges("image", "r")
|
|
||||||
check_provider(params[:provider])
|
|
||||||
json get_images(BaseRoutes.mongo, params[:provider])
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get devops image by id
|
# Create devops image
|
||||||
#
|
#
|
||||||
# * *Request*
|
# * *Request*
|
||||||
# - method : GET
|
# - method : POST
|
||||||
# - headers :
|
# - headers :
|
||||||
# - Accept: application/json
|
# - Accept: application/json
|
||||||
#
|
# - Content-Type: application/json
|
||||||
# * *Returns* :
|
# - body :
|
||||||
# {
|
# {
|
||||||
# "provider": "openstack",
|
# "id": "image id",
|
||||||
# "name": "centos-6.4-x86_64",
|
# "provider": "image provider",
|
||||||
# "remote_user": "root",
|
# "remote_user": "user", -> the ssh username
|
||||||
# "bootstrap_template": null,
|
# "bootstrap_template": null, -> specific bootstrap template name or nil
|
||||||
# "id": "36dc7618-4178-4e29-be43-286fbfe90f50"
|
# "name": "image name"
|
||||||
# }
|
# }
|
||||||
get "/image/:image_id" do
|
#
|
||||||
check_headers :accept
|
# * *Returns* :
|
||||||
check_privileges("image", "r")
|
# 201 - Created
|
||||||
json BaseRoutes.mongo.image(params[:image_id])
|
app.post "/image" do
|
||||||
end
|
check_headers
|
||||||
|
check_privileges("image", "w")
|
||||||
|
image = create_object_from_json_body
|
||||||
|
settings.mongo.image_insert Image.new(image)
|
||||||
|
create_response "Created", nil, 201
|
||||||
|
end
|
||||||
|
|
||||||
# Create devops image
|
# Update devops image
|
||||||
#
|
#
|
||||||
# * *Request*
|
# * *Request*
|
||||||
# - method : POST
|
# - method : PUT
|
||||||
# - headers :
|
# - headers :
|
||||||
# - Accept: application/json
|
# - Accept: application/json
|
||||||
# - Content-Type: application/json
|
# - Content-Type: application/json
|
||||||
# - body :
|
# - body :
|
||||||
# {
|
# {
|
||||||
# "id": "image id",
|
# "id": "image id",
|
||||||
# "provider": "image provider",
|
# "provider": "image provider",
|
||||||
# "remote_user": "user", -> the ssh username
|
# "remote_user": "user" -> the ssh username
|
||||||
# "bootstrap_template": null, -> specific bootstrap template name or nil
|
# "bootstrap_template": null -> specific bootstrap template name or nil
|
||||||
# "name": "image name"
|
# "name": "image name"
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# * *Returns* :
|
# * *Returns* :
|
||||||
# 201 - Created
|
# 200 - Updated
|
||||||
post "/image" do
|
app.put "/image/:image_id" do
|
||||||
check_headers
|
check_headers
|
||||||
check_privileges("image", "w")
|
check_privileges("image", "w")
|
||||||
image = create_object_from_json_body
|
settings.mongo.image params[:image_id]
|
||||||
BaseRoutes.mongo.image_insert Image.new(image)
|
image = Image.new(create_object_from_json_body)
|
||||||
create_response "Created", nil, 201
|
image.id = params[:image_id]
|
||||||
end
|
settings.mongo.image_update image
|
||||||
|
create_response("Image '#{params[:image_id]}' has been updated")
|
||||||
|
end
|
||||||
|
|
||||||
# Update devops image
|
# Delete devops image
|
||||||
#
|
#
|
||||||
# * *Request*
|
# * *Request*
|
||||||
# - method : PUT
|
# - method : DELETE
|
||||||
# - headers :
|
# - headers :
|
||||||
# - Accept: application/json
|
# - Accept: application/json
|
||||||
# - Content-Type: application/json
|
#
|
||||||
# - body :
|
# * *Returns* :
|
||||||
# {
|
# 200 - Deleted
|
||||||
# "id": "image id",
|
app.delete "/image/:image_id" do
|
||||||
# "provider": "image provider",
|
check_headers
|
||||||
# "remote_user": "user" -> the ssh username
|
check_privileges("image", "w")
|
||||||
# "bootstrap_template": null -> specific bootstrap template name or nil
|
projects = settings.mongo.projects_by_image params[:image_id]
|
||||||
# "name": "image name"
|
unless projects.empty?
|
||||||
# }
|
ar = []
|
||||||
#
|
projects.each do |p|
|
||||||
# * *Returns* :
|
ar += p.deploy_envs.select{|e| e.image == params[:image_id]}.map{|e| "#{p.id}.#{e.identifier}"}
|
||||||
# 200 - Updated
|
end
|
||||||
put "/image/:image_id" do
|
raise DependencyError.new "Deleting is forbidden: Image is used in #{ar.join(", ")}"
|
||||||
check_headers
|
end
|
||||||
check_privileges("image", "w")
|
|
||||||
BaseRoutes.mongo.image params[:image_id]
|
|
||||||
image = Image.new(create_object_from_json_body)
|
|
||||||
image.id = params[:image_id]
|
|
||||||
BaseRoutes.mongo.image_update image
|
|
||||||
create_response("Image '#{params[:image_id]}' has been updated")
|
|
||||||
end
|
|
||||||
|
|
||||||
# Delete devops image
|
r = settings.mongo.image_delete params[:image_id]
|
||||||
#
|
create_response("Image '#{params[:image_id]}' has been removed")
|
||||||
# * *Request*
|
end
|
||||||
# - method : DELETE
|
|
||||||
# - headers :
|
puts "Image routes initialized"
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* :
|
|
||||||
# 200 - Deleted
|
|
||||||
delete "/image/:image_id" do
|
|
||||||
check_headers
|
|
||||||
check_privileges("image", "w")
|
|
||||||
projects = BaseRoutes.mongo.projects_by_image params[:image_id]
|
|
||||||
unless projects.empty?
|
|
||||||
ar = []
|
|
||||||
projects.each do |p|
|
|
||||||
ar += p.deploy_envs.select{|e| e.image == params[:image_id]}.map{|e| "#{p.id}.#{e.identifier}"}
|
|
||||||
end
|
end
|
||||||
raise DependencyError.new "Deleting is forbidden: Image is used in #{ar.join(", ")}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
r = BaseRoutes.mongo.image_delete params[:image_id]
|
|
||||||
create_response("Image '#{params[:image_id]}' has been removed")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3,108 +3,111 @@ require "db/exceptions/invalid_record"
|
|||||||
require "db/mongo/models/key"
|
require "db/mongo/models/key"
|
||||||
require "fileutils"
|
require "fileutils"
|
||||||
|
|
||||||
module Version2_0
|
module Devops
|
||||||
class KeyRoutes < BaseRoutes
|
module Version2_0
|
||||||
|
module Core
|
||||||
|
module KeyRoutes
|
||||||
|
|
||||||
def initialize wrapper
|
def self.registered(app)
|
||||||
super wrapper
|
app.before %r{\A/key(/[\w]+)?\z} do
|
||||||
puts "Key routes initialized"
|
if request.delete?
|
||||||
end
|
check_headers :accept
|
||||||
|
else
|
||||||
|
check_headers :accept, :content_type
|
||||||
|
end
|
||||||
|
check_privileges("key", "w")
|
||||||
|
end
|
||||||
|
|
||||||
|
app.after %r{\A/key(/[\w]+)?\z} do
|
||||||
|
statistic
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get list of available ssh keys
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : GET
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
#
|
||||||
|
# * *Returns* : array of strings
|
||||||
|
# [
|
||||||
|
# {
|
||||||
|
# "scope": "system", -> 'system' - key was added by server, 'user' - key was added by user
|
||||||
|
# "id": "devops"
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
app.get "/keys" do
|
||||||
|
check_headers :accept
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create ssh key on devops server
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : POST
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
# - Content-Type: application/json
|
||||||
|
# - body :
|
||||||
|
# {
|
||||||
|
# "file_name": "key file name",
|
||||||
|
# "key_name": "key name",
|
||||||
|
# "content": "key content"
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# * *Returns* :
|
||||||
|
# 201 - Created
|
||||||
|
app.post "/key" do
|
||||||
|
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")
|
||||||
|
content = check_string(key["content"], "Parameter 'content' should be a not empty string")
|
||||||
|
file_name = File.join(DevopsService.config[:keys_dir], fname)
|
||||||
|
halt(400, "File '#{fname}' already exist") if File.exists?(file_name)
|
||||||
|
File.open(file_name, "w") do |f|
|
||||||
|
f.write(content)
|
||||||
|
f.chmod(0400)
|
||||||
|
end
|
||||||
|
|
||||||
|
key = Key.new({"path" => file_name, "id" => kname})
|
||||||
|
settings.mongo.key_insert key
|
||||||
|
create_response("Created", nil, 201)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delete ssh key from devops server
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : DELETE
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
#
|
||||||
|
# * *Returns* :
|
||||||
|
# 200 - Deleted
|
||||||
|
app.delete "/key/:key" do
|
||||||
|
servers = settings.mongo.servers_by_key params[:key]
|
||||||
|
unless servers.empty?
|
||||||
|
s_str = servers.map{|s| s.id}.join(", ")
|
||||||
|
raise DependencyError.new "Deleting is forbidden: Key is used in servers: #{s_str}"
|
||||||
|
end
|
||||||
|
|
||||||
|
k = settings.mongo.key params[:key]
|
||||||
|
begin
|
||||||
|
FileUtils.rm(k.path)
|
||||||
|
rescue
|
||||||
|
logger.error "Missing key file for #{params[:key]} - #{k.filename}"
|
||||||
|
end
|
||||||
|
r = settings.mongo.key_delete params[:key]
|
||||||
|
return [500, r["err"].inspect] unless r["err"].nil?
|
||||||
|
create_response("Key '#{params[:key]}' removed")
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Key routes initialized"
|
||||||
|
end
|
||||||
|
|
||||||
before %r{\A/key(/[\w]+)?\z} do
|
|
||||||
if request.delete?
|
|
||||||
check_headers :accept
|
|
||||||
else
|
|
||||||
check_headers :accept, :content_type
|
|
||||||
end
|
end
|
||||||
check_privileges("key", "w")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
after %r{\A/key(/[\w]+)?\z} do
|
|
||||||
statistic
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get list of available ssh keys
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : GET
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* : array of strings
|
|
||||||
# [
|
|
||||||
# {
|
|
||||||
# "scope": "system", -> 'system' - key was added by server, 'user' - key was added by user
|
|
||||||
# "id": "devops"
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
get "/keys" do
|
|
||||||
check_headers :accept
|
|
||||||
check_privileges("key", "r")
|
|
||||||
keys = BaseRoutes.mongo.keys.map {|i| i.to_hash}
|
|
||||||
keys.each {|k| k.delete("path")} # We should not return path to the key
|
|
||||||
json keys
|
|
||||||
end
|
|
||||||
|
|
||||||
# Create ssh key on devops server
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : POST
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
# - Content-Type: application/json
|
|
||||||
# - body :
|
|
||||||
# {
|
|
||||||
# "file_name": "key file name",
|
|
||||||
# "key_name": "key name",
|
|
||||||
# "content": "key content"
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# * *Returns* :
|
|
||||||
# 201 - Created
|
|
||||||
post "/key" do
|
|
||||||
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")
|
|
||||||
content = check_string(key["content"], "Parameter 'content' should be a not empty string")
|
|
||||||
file_name = File.join(DevopsService.config[:keys_dir], fname)
|
|
||||||
halt(400, "File '#{fname}' already exist") if File.exists?(file_name)
|
|
||||||
File.open(file_name, "w") do |f|
|
|
||||||
f.write(content)
|
|
||||||
f.chmod(0400)
|
|
||||||
end
|
|
||||||
|
|
||||||
key = Key.new({"path" => file_name, "id" => kname})
|
|
||||||
BaseRoutes.mongo.key_insert key
|
|
||||||
create_response("Created", nil, 201)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Delete ssh key from devops server
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : DELETE
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* :
|
|
||||||
# 200 - Deleted
|
|
||||||
delete "/key/:key" do
|
|
||||||
servers = BaseRoutes.mongo.servers_by_key params[:key]
|
|
||||||
unless servers.empty?
|
|
||||||
s_str = servers.map{|s| s.id}.join(", ")
|
|
||||||
raise DependencyError.new "Deleting is forbidden: Key is used in servers: #{s_str}"
|
|
||||||
end
|
|
||||||
|
|
||||||
k = BaseRoutes.mongo.key params[:key]
|
|
||||||
begin
|
|
||||||
FileUtils.rm(k.path)
|
|
||||||
rescue
|
|
||||||
logger.error "Missing key file for #{params[:key]} - #{k.filename}"
|
|
||||||
end
|
|
||||||
r = BaseRoutes.mongo.key_delete params[:key]
|
|
||||||
return [500, r["err"].inspect] unless r["err"].nil?
|
|
||||||
create_response("Key '#{params[:key]}' removed")
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,49 +1,51 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
require "json"
|
require "json"
|
||||||
require "routes/v2.0/base_routes"
|
|
||||||
require "providers/provider_factory"
|
require "providers/provider_factory"
|
||||||
|
|
||||||
module Version2_0
|
module Devops
|
||||||
class NetworkRoutes < BaseRoutes
|
module Version2_0
|
||||||
|
module Core
|
||||||
|
module NetworkRoutes
|
||||||
|
|
||||||
def initialize wrapper
|
def self.registered(app)
|
||||||
super wrapper
|
# Get list of networks for :provider
|
||||||
puts "Network routes initialized"
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : GET
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
#
|
||||||
|
# * *Returns* : array of strings
|
||||||
|
# - ec2:
|
||||||
|
# [
|
||||||
|
# {
|
||||||
|
# "cidr": "0.0.0.0/16",
|
||||||
|
# "vpcId": "vpc-1",
|
||||||
|
# "subnetId": "subnet-1",
|
||||||
|
# "name": "subnet-1",
|
||||||
|
# "zone": "us-east-1a"
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
# - openstack:
|
||||||
|
# [
|
||||||
|
# {
|
||||||
|
# "cidr": "0.0.0.0/16",
|
||||||
|
# "name": "private",
|
||||||
|
# "id": "b14f8df9-ac27-48e2-8d65-f7ef78dc2654"
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
app.get "/networks/:provider" do
|
||||||
|
check_headers :accept
|
||||||
|
check_privileges("network", "r")
|
||||||
|
check_provider(params[:provider])
|
||||||
|
p = ::Provider::ProviderFactory.get params[:provider]
|
||||||
|
json p.networks_detail
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Network routes initialized"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get list of networks for :provider
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : GET
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* : array of strings
|
|
||||||
# - ec2:
|
|
||||||
# [
|
|
||||||
# {
|
|
||||||
# "cidr": "0.0.0.0/16",
|
|
||||||
# "vpcId": "vpc-1",
|
|
||||||
# "subnetId": "subnet-1",
|
|
||||||
# "name": "subnet-1",
|
|
||||||
# "zone": "us-east-1a"
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
# - openstack:
|
|
||||||
# [
|
|
||||||
# {
|
|
||||||
# "cidr": "0.0.0.0/16",
|
|
||||||
# "name": "private",
|
|
||||||
# "id": "b14f8df9-ac27-48e2-8d65-f7ef78dc2654"
|
|
||||||
# }
|
|
||||||
# ]
|
|
||||||
get "/networks/:provider" do
|
|
||||||
check_headers :accept
|
|
||||||
check_privileges("network", "r")
|
|
||||||
check_provider(params[:provider])
|
|
||||||
p = ::Provider::ProviderFactory.get params[:provider]
|
|
||||||
json p.networks_detail
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,14 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'sinatra/base'
|
|
||||||
|
|
||||||
require "json"
|
require "json"
|
||||||
require "routes/v2.0/base_routes"
|
|
||||||
require "providers/provider_factory"
|
require "providers/provider_factory"
|
||||||
|
|
||||||
module Sinatra
|
module Devops
|
||||||
module Version2_0
|
module Version2_0
|
||||||
module Core
|
module Core
|
||||||
module ProviderRoutes
|
module ProviderRoutes
|
||||||
|
|
||||||
def self.registered(app)
|
def self.registered(app)
|
||||||
puts "Provider routes initialized"
|
|
||||||
|
|
||||||
# Get devops providers
|
# Get devops providers
|
||||||
#
|
#
|
||||||
@ -31,6 +27,8 @@ module Sinatra
|
|||||||
check_privileges("provider", "r")
|
check_privileges("provider", "r")
|
||||||
json ::Provider::ProviderFactory.providers
|
json ::Provider::ProviderFactory.providers
|
||||||
end
|
end
|
||||||
|
|
||||||
|
puts "Provider routes initialized"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,181 +1,184 @@
|
|||||||
require "providers/provider_factory"
|
require "providers/provider_factory"
|
||||||
require "routes/v2.0/base_routes"
|
|
||||||
require "fileutils"
|
require "fileutils"
|
||||||
require "commands/status"
|
require "commands/status"
|
||||||
|
|
||||||
module Version2_0
|
module Devops
|
||||||
class ScriptRoutes < BaseRoutes
|
module Version2_0
|
||||||
|
module Core
|
||||||
|
module ScriptRoutes
|
||||||
|
|
||||||
include StatusCommands
|
extend StatusCommands
|
||||||
|
|
||||||
def initialize wrapper
|
def self.registered(app)
|
||||||
super wrapper
|
app.before "/script/:script_name" do
|
||||||
puts "Script routes initialized"
|
check_headers :accept
|
||||||
end
|
check_privileges("script", "w")
|
||||||
|
file_name = params[:script_name]
|
||||||
before "/script/:script_name" do
|
@file = File.join(DevopsService.config[:scripts_dir], check_filename(file_name, "Parameter 'script_name' must be a not empty string"))
|
||||||
check_headers :accept
|
if request.put?
|
||||||
check_privileges("script", "w")
|
halt_response("File '#{file_name}' already exist") if File.exists?(@file)
|
||||||
file_name = params[:script_name]
|
elsif request.delete?
|
||||||
@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)
|
||||||
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
|
|
||||||
|
|
||||||
after %r{\A/script/((command|run)/)?[\w]+\z} do
|
|
||||||
statistic
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get scripts names
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : GET
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* :
|
|
||||||
# [
|
|
||||||
# "script_1"
|
|
||||||
# ]
|
|
||||||
get "/scripts" do
|
|
||||||
check_headers :accept
|
|
||||||
check_privileges("script", "r")
|
|
||||||
res = []
|
|
||||||
Dir.foreach(DevopsService.config[:scripts_dir]) {|f| res.push(f) unless f.start_with?(".")}
|
|
||||||
json res
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run command on node :node_name
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : POST
|
|
||||||
# - body :
|
|
||||||
# command to run
|
|
||||||
#
|
|
||||||
# * *Returns* : text stream
|
|
||||||
post "/script/command/:node_name" do
|
|
||||||
check_privileges("script", "x")
|
|
||||||
user = request.env['REMOTE_USER']
|
|
||||||
s = BaseRoutes.mongo.server_by_chef_node_name params[:node_name]
|
|
||||||
BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, user
|
|
||||||
cert = BaseRoutes.mongo.key s.key
|
|
||||||
cmd = request.body.read
|
|
||||||
addr = "#{s.remote_user}@#{s.public_ip || s.private_ip}"
|
|
||||||
ssh_cmd = "ssh -i %s #{addr} '#{cmd}'"
|
|
||||||
stream() do |out|
|
|
||||||
begin
|
|
||||||
out << ssh_cmd % File.basename(cert.path)
|
|
||||||
out << "\n"
|
|
||||||
IO.popen((ssh_cmd % cert.path) + " 2>&1") do |so|
|
|
||||||
while line = so.gets do
|
|
||||||
out << line
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
out << "\nDone"
|
|
||||||
rescue IOError => e
|
|
||||||
logger.error e.message
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run script :script_name on nodes
|
app.after %r{\A/script/((command|run)/)?[\w]+\z} do
|
||||||
#
|
statistic
|
||||||
# * *Request*
|
end
|
||||||
# - method : POST
|
|
||||||
# - headers :
|
|
||||||
# - Content-Type: application/json
|
|
||||||
# - body :
|
|
||||||
# {
|
|
||||||
# "nodes": [], -> array of nodes names
|
|
||||||
# "params": [] -> array of script arguments
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# * *Returns* : text stream
|
|
||||||
post "/script/run/:script_name" do
|
|
||||||
check_headers :content_type
|
|
||||||
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)
|
|
||||||
body = create_object_from_json_body
|
|
||||||
nodes = check_array(body["nodes"], "Parameter 'nodes' must be a not empty array of strings")
|
|
||||||
p = check_array(body["params"], "Parameter 'params' should be a not empty array of strings", String, true)
|
|
||||||
servers = BaseRoutes.mongo.servers_by_names(nodes)
|
|
||||||
return [404, "No servers found for names '#{nodes.join("', '")}'"] if servers.empty?
|
|
||||||
user = request.env['REMOTE_USER']
|
|
||||||
servers.each do |s|
|
|
||||||
BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, user
|
|
||||||
end
|
|
||||||
stream() do |out|
|
|
||||||
begin
|
|
||||||
status = []
|
|
||||||
servers.each do |s|
|
|
||||||
cert = begin
|
|
||||||
BaseRoutes.mongo.key s.key
|
|
||||||
rescue
|
|
||||||
out << "No key found for '#{s.chef_node_name}'"
|
|
||||||
status.push 2
|
|
||||||
next
|
|
||||||
end
|
|
||||||
ssh_cmd = "ssh -i #{cert.path} #{s.remote_user}@#{s.public_ip || s.private_ip} 'bash -s' < %s"
|
|
||||||
out << "\nRun script on '#{s.chef_node_name}'\n"
|
|
||||||
unless p.nil?
|
|
||||||
ssh_cmd += " " + p.join(" ")
|
|
||||||
end
|
|
||||||
out << (ssh_cmd % [params[:script_name]])
|
|
||||||
out << "\n"
|
|
||||||
|
|
||||||
begin
|
# Get scripts names
|
||||||
IO.popen( (ssh_cmd % [@file]) + " 2>&1") do |so|
|
#
|
||||||
while line = so.gets do
|
# * *Request*
|
||||||
out << line
|
# - method : GET
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
#
|
||||||
|
# * *Returns* :
|
||||||
|
# [
|
||||||
|
# "script_1"
|
||||||
|
# ]
|
||||||
|
app.get "/scripts" do
|
||||||
|
check_headers :accept
|
||||||
|
check_privileges("script", "r")
|
||||||
|
res = []
|
||||||
|
Dir.foreach(DevopsService.config[:scripts_dir]) {|f| res.push(f) unless f.start_with?(".")}
|
||||||
|
json res
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run command on node :node_name
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : POST
|
||||||
|
# - body :
|
||||||
|
# command to run
|
||||||
|
#
|
||||||
|
# * *Returns* : text stream
|
||||||
|
app.post "/script/command/:node_name" do
|
||||||
|
check_privileges("script", "x")
|
||||||
|
user = request.env['REMOTE_USER']
|
||||||
|
s = BaseRoutes.mongo.server_by_chef_node_name params[:node_name]
|
||||||
|
BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, user
|
||||||
|
cert = BaseRoutes.mongo.key s.key
|
||||||
|
cmd = request.body.read
|
||||||
|
addr = "#{s.remote_user}@#{s.public_ip || s.private_ip}"
|
||||||
|
ssh_cmd = "ssh -i %s #{addr} '#{cmd}'"
|
||||||
|
stream() do |out|
|
||||||
|
begin
|
||||||
|
out << ssh_cmd % File.basename(cert.path)
|
||||||
|
out << "\n"
|
||||||
|
IO.popen((ssh_cmd % cert.path) + " 2>&1") do |so|
|
||||||
|
while line = so.gets do
|
||||||
|
out << line
|
||||||
|
end
|
||||||
end
|
end
|
||||||
so.close
|
out << "\nDone"
|
||||||
status.push $?.to_i
|
rescue IOError => e
|
||||||
|
logger.error e.message
|
||||||
end
|
end
|
||||||
rescue IOError => e
|
|
||||||
logger.error e.message
|
|
||||||
out << e.message
|
|
||||||
status.push 3
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
out << create_status(status)
|
|
||||||
rescue IOError => e
|
# Run script :script_name on nodes
|
||||||
logger.error e.message
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : POST
|
||||||
|
# - headers :
|
||||||
|
# - Content-Type: application/json
|
||||||
|
# - body :
|
||||||
|
# {
|
||||||
|
# "nodes": [], -> array of nodes names
|
||||||
|
# "params": [] -> array of script arguments
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# * *Returns* : text stream
|
||||||
|
app.post "/script/run/:script_name" do
|
||||||
|
check_headers :content_type
|
||||||
|
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)
|
||||||
|
body = create_object_from_json_body
|
||||||
|
nodes = check_array(body["nodes"], "Parameter 'nodes' must be a not empty array of strings")
|
||||||
|
p = check_array(body["params"], "Parameter 'params' should be a not empty array of strings", String, true)
|
||||||
|
servers = BaseRoutes.mongo.servers_by_names(nodes)
|
||||||
|
return [404, "No servers found for names '#{nodes.join("', '")}'"] if servers.empty?
|
||||||
|
user = request.env['REMOTE_USER']
|
||||||
|
servers.each do |s|
|
||||||
|
BaseRoutes.mongo.check_project_auth s.project, s.deploy_env, user
|
||||||
|
end
|
||||||
|
stream() do |out|
|
||||||
|
begin
|
||||||
|
status = []
|
||||||
|
servers.each do |s|
|
||||||
|
cert = begin
|
||||||
|
BaseRoutes.mongo.key s.key
|
||||||
|
rescue
|
||||||
|
out << "No key found for '#{s.chef_node_name}'"
|
||||||
|
status.push 2
|
||||||
|
next
|
||||||
|
end
|
||||||
|
ssh_cmd = "ssh -i #{cert.path} #{s.remote_user}@#{s.public_ip || s.private_ip} 'bash -s' < %s"
|
||||||
|
out << "\nRun script on '#{s.chef_node_name}'\n"
|
||||||
|
unless p.nil?
|
||||||
|
ssh_cmd += " " + p.join(" ")
|
||||||
|
end
|
||||||
|
out << (ssh_cmd % [params[:script_name]])
|
||||||
|
out << "\n"
|
||||||
|
|
||||||
|
begin
|
||||||
|
IO.popen( (ssh_cmd % [@file]) + " 2>&1") do |so|
|
||||||
|
while line = so.gets do
|
||||||
|
out << line
|
||||||
|
end
|
||||||
|
so.close
|
||||||
|
status.push $?.to_i
|
||||||
|
end
|
||||||
|
rescue IOError => e
|
||||||
|
logger.error e.message
|
||||||
|
out << e.message
|
||||||
|
status.push 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
out << create_status(status)
|
||||||
|
rescue IOError => e
|
||||||
|
logger.error e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create script :script_name
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : PUT
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
# - body : script content
|
||||||
|
#
|
||||||
|
# * *Returns* :
|
||||||
|
# 201 - Created
|
||||||
|
app.put "/script/:script_name" do
|
||||||
|
File.open(@file, "w") {|f| f.write(request.body.read)}
|
||||||
|
create_response("File '#{params[:script_name]}' created", nil, 201)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delete script :script_name
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : Delete
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
#
|
||||||
|
# * *Returns* :
|
||||||
|
# 200 - Deleted
|
||||||
|
app.delete "/script/:script_name" do
|
||||||
|
FileUtils.rm(@file)
|
||||||
|
create_response("File '#{params[:script_name]}' deleted")
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Script routes initialized"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create script :script_name
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : PUT
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
# - body : script content
|
|
||||||
#
|
|
||||||
# * *Returns* :
|
|
||||||
# 201 - Created
|
|
||||||
put "/script/:script_name" do
|
|
||||||
File.open(@file, "w") {|f| f.write(request.body.read)}
|
|
||||||
create_response("File '#{params[:script_name]}' created", nil, 201)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Delete script :script_name
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : Delete
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* :
|
|
||||||
# 200 - Deleted
|
|
||||||
delete "/script/:script_name" do
|
|
||||||
FileUtils.rm(@file)
|
|
||||||
create_response("File '#{params[:script_name]}' deleted")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,21 +1,24 @@
|
|||||||
require "json"
|
require "json"
|
||||||
require "routes/v2.0/base_routes"
|
|
||||||
require "sidekiq"
|
require "sidekiq"
|
||||||
|
|
||||||
module Version2_0
|
module Devops
|
||||||
class StatusRoutes < BaseRoutes
|
module Version2_0
|
||||||
|
module Core
|
||||||
|
module StatusRoutes
|
||||||
|
|
||||||
def initialize wrapper
|
def self.registered(app)
|
||||||
super wrapper
|
app.get "/status/:id" do
|
||||||
puts "Status routes initialized"
|
r = Sidekiq.redis do |connection|
|
||||||
end
|
connection.hget("devops", params[:id])
|
||||||
|
end
|
||||||
|
return [404, "Job with id '#{params[:id]}' not found"] if r.nil?
|
||||||
|
r
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Status routes initialized"
|
||||||
|
end
|
||||||
|
|
||||||
get "/status/:id" do
|
|
||||||
r = Sidekiq.redis do |connection|
|
|
||||||
connection.hget("devops", params[:id])
|
|
||||||
end
|
end
|
||||||
return [404, "Job with id '#{params[:id]}' not found"] if r.nil?
|
|
||||||
r
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,87 +1,91 @@
|
|||||||
require "commands/knife_commands"
|
require "commands/knife_commands"
|
||||||
|
|
||||||
module Version2_0
|
module Devops
|
||||||
class TagRoutes < BaseRoutes
|
module Version2_0
|
||||||
|
module Core
|
||||||
|
module TagRoutes
|
||||||
|
|
||||||
def initialize wrapper
|
def self.registered(app)
|
||||||
super wrapper
|
app.before "/tags/:node_name" do
|
||||||
puts "Tag routes initialized"
|
if request.get?
|
||||||
end
|
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 = BaseRoutes.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
|
||||||
|
|
||||||
|
# Get tags list for :node_name
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : GET
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
#
|
||||||
|
# * *Returns* :
|
||||||
|
# [
|
||||||
|
# "tag_1"
|
||||||
|
# ]
|
||||||
|
app.get "/tags/:node_name" do
|
||||||
|
json(KnifeCommands.tags_list(@chef_node_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Set tags list to :node_name
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : POST
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
# - Content-Type: application/json
|
||||||
|
# - body :
|
||||||
|
# [
|
||||||
|
# "tag_1"
|
||||||
|
# ]
|
||||||
|
#
|
||||||
|
# * *Returns* :
|
||||||
|
# 200
|
||||||
|
app.post "/tags/:node_name" do
|
||||||
|
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
|
||||||
|
|
||||||
|
# Delete tags from :node_name
|
||||||
|
#
|
||||||
|
# * *Request*
|
||||||
|
# - method : DELETE
|
||||||
|
# - headers :
|
||||||
|
# - Accept: application/json
|
||||||
|
# - Content-Type: application/json
|
||||||
|
# - body :
|
||||||
|
# [
|
||||||
|
# "tag_1"
|
||||||
|
# ]
|
||||||
|
#
|
||||||
|
# * *Returns* :
|
||||||
|
# 200
|
||||||
|
app.delete "/tags/:node_name" do
|
||||||
|
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
|
||||||
|
|
||||||
|
puts "Tag routes initialized"
|
||||||
|
end
|
||||||
|
|
||||||
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
|
end
|
||||||
server = BaseRoutes.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
|
|
||||||
|
|
||||||
after "/tags/:node_name" do
|
|
||||||
statistic
|
|
||||||
end
|
|
||||||
|
|
||||||
# Get tags list for :node_name
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : GET
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
#
|
|
||||||
# * *Returns* :
|
|
||||||
# [
|
|
||||||
# "tag_1"
|
|
||||||
# ]
|
|
||||||
get "/tags/:node_name" do
|
|
||||||
json(KnifeCommands.tags_list(@chef_node_name))
|
|
||||||
end
|
|
||||||
|
|
||||||
# Set tags list to :node_name
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : POST
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
# - Content-Type: application/json
|
|
||||||
# - body :
|
|
||||||
# [
|
|
||||||
# "tag_1"
|
|
||||||
# ]
|
|
||||||
#
|
|
||||||
# * *Returns* :
|
|
||||||
# 200
|
|
||||||
post "/tags/:node_name" do
|
|
||||||
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
|
|
||||||
|
|
||||||
# Delete tags from :node_name
|
|
||||||
#
|
|
||||||
# * *Request*
|
|
||||||
# - method : DELETE
|
|
||||||
# - headers :
|
|
||||||
# - Accept: application/json
|
|
||||||
# - Content-Type: application/json
|
|
||||||
# - body :
|
|
||||||
# [
|
|
||||||
# "tag_1"
|
|
||||||
# ]
|
|
||||||
#
|
|
||||||
# * *Returns* :
|
|
||||||
# 200
|
|
||||||
delete "/tags/:node_name" do
|
|
||||||
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
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
require "db/exceptions/invalid_record"
|
require "db/exceptions/invalid_record"
|
||||||
require "db/mongo/models/user"
|
require "db/mongo/models/user"
|
||||||
|
|
||||||
module Sinatra
|
module Devops
|
||||||
module Version2_0
|
module Version2_0
|
||||||
module Core
|
module Core
|
||||||
module UserRoutes
|
module UserRoutes
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user