Skip to content

Commit 57dd142

Browse files
committed
first commit: support domains
0 parents  commit 57dd142

24 files changed

+1182
-0
lines changed

.bowerrc

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"directory": "client/libs",
3+
"interactive" : false
4+
}

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
/.idea/
3+
/Gemfile.lock
4+
/client/lib
5+
/conf/

.rspec

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
--color
2+
--require spec_helper

.travis.yml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
sudo: false
2+
language: ruby
3+
rvm:
4+
- 2.0.0
5+
- 2.1.10
6+
- 2.2.7
7+
- 2.3.3
8+
- 2.3.4
9+
- 2.4.0
10+
- 2.4.1
11+
before_install: gem install bundler
12+
install: bundle
13+
script:
14+
- bundle exec rspec
15+
deploy:
16+
-

Dockerfile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM wuhuizuo/docker-ruby
2+
3+
ADD ./ /app
4+
5+
WORKDIR /app
6+
7+
CMD ['./start.sh']

Gemfile

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
source :rubygems
2+
3+
gem 'sinatra'
4+
gem 'sinatra-contrib'
5+
gem 'thin'
6+
gem 'roo'
7+
gem 'net-ssh'
8+
gem 'net-sftp'
9+
gem 'tes-request', '>= 0.7'
10+
11+
group :test do
12+
gem 'rack-test'
13+
end
14+
15+
group :test, :development do
16+
gem 'rspec', '~> 3.6.0'
17+
end

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
测试资源调度服务
2+
=======
3+
4+
本项目旨在为软件测试提供配套的环境资源调度,简化在自动化项目中的自动化环境/资源管理
5+
6+

Rakefile

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
require 'rspec/core/rake_task'
2+
3+
RSpec::Core::RakeTask.new :specs do |task|
4+
task.pattern = Dir['spec/**/*_spec.rb']
5+
end
6+
7+
task :default => ['specs']
8+
9+
desc 'generate new uuid'
10+
task :gen_uuid do
11+
require 'securerandom'
12+
puts SecureRandom.uuid
13+
end

app.rb

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
ENV['RACK_ENV'] ||= 'development'
2+
3+
require 'bundler'
4+
Bundler.require :default, ENV['RACK_ENV'].to_sym
5+
6+
require_relative 'lib/env_manager'
7+
require 'logger'
8+
require 'json'
9+
require 'sinatra/base'
10+
require 'sinatra/json'
11+
12+
module Tes
13+
class App < Sinatra::Base
14+
# 初始化
15+
@@domains = {}
16+
17+
def self.add_domain(name)
18+
if @@domains[name]
19+
false
20+
else
21+
config_file = File.join(__dir__, 'conf', 'domains', name, 'resource.yml')
22+
server = EnvManager.new config_file
23+
@@domains.merge!(name => server)
24+
true
25+
end
26+
end
27+
28+
set :logging, true
29+
set :show_exceptions, :after_handler
30+
31+
configure :production do
32+
# set :clean_trace, true
33+
# set :dump_errors, false
34+
Dir.mkdir('logs') unless File.exist?('logs')
35+
36+
$logger = Logger.new('logs/common.log', 'weekly')
37+
$logger.level = Logger::WARN
38+
39+
# Spit stdout and stderr to a file during production
40+
# in case something goes wrong
41+
$stdout.reopen('logs/output.log', 'w')
42+
$stdout.sync = true
43+
$stderr.reopen($stdout)
44+
45+
# 初始化配置
46+
Dir.glob("#{__dir__}/conf/domains/*/resource.yml").each do |f|
47+
add_domain File.basename(File.dirname(f))
48+
end
49+
end
50+
51+
configure :development do
52+
$logger = Logger.new(STDOUT)
53+
end
54+
55+
set :root, __dir__
56+
set :public_folder, File.join(__dir__, 'client')
57+
58+
def return_error(e)
59+
status 500
60+
json success: false, error: {message: e.message, detail: e.backtrace.join("\n")}
61+
end
62+
63+
def deal_block(&block)
64+
block.call
65+
rescue RuntimeError => e
66+
return_error e
67+
end
68+
69+
def get_domain(domain)
70+
domain_server = @@domains[domain]
71+
if domain_server
72+
block_given? ? yield(domain_server) : domain_server
73+
else
74+
status 500
75+
json success: false, error: {message: "No domain:#{domain} served!"}
76+
end
77+
end
78+
79+
error RuntimeError do
80+
e = env['sinatra.error']
81+
$logger.error e.message
82+
json success: false, error: {message: e.message, detail: e.backtrace.join("\n")}
83+
end
84+
85+
get '/' do
86+
erb :index
87+
end
88+
89+
get '/domains' do
90+
json(success: true, data: @@domains.keys)
91+
end
92+
93+
put '/domains' do
94+
domain_name = request.body.read.strip
95+
if domain_name =~ /.+/
96+
json(success: self.class.add_domain(domain_name))
97+
else
98+
json(success: false, error: {message: 'domain name should not be empty'})
99+
end
100+
101+
end
102+
103+
get '/:domain/res' do |domain|
104+
get_domain(domain) {|server| json(success: true, data: server.resources)}
105+
end
106+
107+
put '/:domain/res' do |domain|
108+
get_domain(domain) do |server|
109+
res_cfg = JSON.parse(request.body.read, :symbolize_names => true)
110+
res_id = server.add_res(res_cfg)
111+
json(success: true, data: res_id)
112+
end
113+
end
114+
115+
get '/:domain/res/:id' do |domain, res_id|
116+
get_domain(domain) do |server|
117+
res = server.get_res(res_id)
118+
json(success: true, data: res)
119+
end
120+
end
121+
122+
post '/:domain/res/:id' do |domain, res_id|
123+
deal_block do
124+
get_domain(domain) do |server|
125+
detail = JSON.parse(request.body.read, :symbolize_names => true)
126+
server.update_res(res_id, detail)
127+
json success: true
128+
end
129+
end
130+
end
131+
132+
delete '/:domain/res/:id' do |domain, res_id|
133+
deal_block do
134+
get_domain(domain) do |server|
135+
res = server.destroy_res(res_id)
136+
json(success: res ? true : false, data: res)
137+
end
138+
end
139+
end
140+
141+
post '/:domain/res/:id/lock' do |domain, res_id|
142+
user, lock = params[:user], params[:lock]
143+
lock = (lock.to_i == 1 ? true : false)
144+
get_domain(domain) do |server|
145+
ret = server.lock_res(res_id, user, lock)
146+
json(success: ret ? true : false, data: ret)
147+
end
148+
end
149+
150+
post '/:domain/res/:id/release' do |domain, res_id|
151+
user = params[:user]
152+
get_domain(domain) do |server|
153+
server.release_res(res_id, user)
154+
json(success: true)
155+
end
156+
end
157+
158+
post '/:domain/env/lock' do |domain|
159+
to_locks = JSON.parse(request.body.read, :symbolize_names => true)
160+
user, list, lock = to_locks[:user], to_locks[:list], to_locks[:lock]
161+
lock = (lock.to_i == 1 ? true : false)
162+
get_domain(domain) do |server|
163+
got_list = server.lock_res_list(user, Hash[list.map {|e| [e, lock]}])
164+
json(success: got_list ? true : false, data: got_list)
165+
end
166+
end
167+
168+
post '/:domain/env' do |domain|
169+
data = JSON.parse(request.body.read, :symbolize_names => true)
170+
ask, user = data[:ask], data[:user]
171+
get_domain(domain) do |server|
172+
ret = server.request_env(user, ask)
173+
if ret[:res].empty?
174+
json(success: false, data: ret)
175+
else
176+
json(success: true, data: ret)
177+
end
178+
end
179+
end
180+
end
181+
end

bower.json

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "tes-web",
3+
"version": "0.0.1",
4+
"authors": [
5+
"wuhuizuo <[email protected]>"
6+
],
7+
"license": "MIT",
8+
"ignore": [
9+
"**/.*",
10+
"node_modules",
11+
"bower_components",
12+
"test",
13+
"tests"
14+
],
15+
"dependencies": {
16+
"angular": "~1.5.6",
17+
"angular-route": "~1.5.6",
18+
"bootstrap": "~3.3.6",
19+
"ace": "latest",
20+
"angular-ui-ace": "bower",
21+
"ng-jsoneditor": "latest"
22+
}
23+
}

client/css/layout.css

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
body {
2+
padding-top: 5rem;
3+
}
4+
.tes-template {
5+
padding: 2rem 1rem;
6+
text-align: left;
7+
}
8+
9+
span.editdelete {
10+
float: right;
11+
}
12+
.res {
13+
background: none repeat scroll 0% 0% rgb(238, 238, 238);
14+
width: 500px;
15+
left: auto;
16+
font-family: arial;
17+
font-size: 9pt;
18+
margin-bottom: 10px;
19+
margin-left: 15px;
20+
margin-right: 15px;
21+
float: left;
22+
color: rgb(51, 51, 51);
23+
box-shadow: 0px 0px 5px rgba(34, 25, 25, 0.5);
24+
border-radius: 8px 8px 8px 8px;
25+
}
26+
.res_footer {
27+
margin-bottom: 5px;
28+
margin-left: 55px;
29+
margin-right: 5px;
30+
}
31+
.editor .outer textarea.text{
32+
min-height: 300px;
33+
height: auto;
34+
}
35+

client/js/app.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
window.app = angular.module('TES', ['ngRoute', 'ui.ace', 'ng.jsoneditor']).config(['$routeProvider',
2+
function ($routeProvider) {
3+
$routeProvider.when('/res/list', {
4+
templateUrl: '../partials/res/list.html',
5+
controller: 'ResList'
6+
}).when('/res/add', {
7+
templateUrl: '../partials/res/add.html',
8+
controller: 'ResAdd'
9+
}).when('/res/all', {
10+
templateUrl: '../partials/res/all.html',
11+
controller: 'ResAll'
12+
}).otherwise({
13+
redirectTo: '/res/list'
14+
});
15+
}
16+
]);

0 commit comments

Comments
 (0)