Merge branch 'dev_devops' of http://gitea.trustie.net/jasder/forgeplus into dev_devops

This commit is contained in:
sylor_huang@126.com
2020-07-22 16:43:09 +08:00
10 changed files with 366 additions and 218 deletions

View File

@@ -342,7 +342,8 @@ class ApplicationController < ActionController::Base
elsif params[:debug] == 'student'
User.current = User.find 8686
elsif params[:debug] == 'admin'
user = User.find 1
logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
user = User.find 36480
User.current = user
cookies.signed[:user_id] = user.id
end
@@ -384,7 +385,7 @@ class ApplicationController < ActionController::Base
def current_user
if Rails.env.development?
User.current = User.find 1
User.current = User.find 36480
else
User.current
end
@@ -743,6 +744,11 @@ class ApplicationController < ActionController::Base
interactor.success? ? render_ok : render_error(interactor.error)
end
# devops 权限验证
def devops_authorize!
render_forbidden unless @project.owner?(current_user)
end
private
def object_not_found
uid_logger("Missing template or cant't find record, responding with 404")

View File

@@ -1,43 +1,59 @@
class ::DevOps::BuildsController < ApplicationController
class DevOps::BuildsController < ApplicationController
include RepositoriesHelper
before_action :require_login
before_action :find_repo
before_action :find_project
before_action :devops_authorize!
def index
cloud_account = @repo.dev_ops_cloud_account
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @repo.user.login, @repo.identifier).builds
cloud_account = @project.dev_ops_cloud_account
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @project.owner.login, @project.identifier).builds
render json: result
end
def detail
cloud_account = @repo.dev_ops_cloud_account
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @repo.user.login, @repo.identifier, number: params[:number]).build
cloud_account = @project.dev_ops_cloud_account
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @project.owner.login, @project.identifier, number: params[:number]).build
render json: result
end
def restart
cloud_account = @repo.dev_ops_cloud_account
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @repo.user.login, @repo.identifier, number: params[:number]).restart
cloud_account = @project.dev_ops_cloud_account
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @project.owner.login, @project.identifier, number: params[:number]).restart
render json: result
end
def delete
cloud_account = @repo.dev_ops_cloud_account
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @repo.user.login, @repo.identifier, number: params[:number]).stop
cloud_account = @project.dev_ops_cloud_account
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @project.owner.login, @project.identifier, number: params[:number]).stop
render json: result
end
def logs
cloud_account = @repo.dev_ops_cloud_account
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @repo.user.login, @repo.identifier, build: params[:build], stage: params[:stage], step: sync_params[:step]).logs
cloud_account = @project.dev_ops_cloud_account
result = DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, @project.owner.login, @project.identifier, build: params[:number], stage: params[:stage], step: params[:step]).logs
render json: result
end
# get .trustie-pipeline.yml file
def get_trustie_pipeline
file_path_uri = URI.parse('.trustie-pipeline.yml')
interactor = Repositories::EntriesInteractor.call(@project.owner, @project.identifier, file_path_uri, ref: params[:ref] || "master")
if interactor.success?
file = interactor.result
return render json: {} if file[:status]
json = {name: file['name'], path: file['path'], content: render_decode64_content(file['content'])}
render json: json
end
end
private
def find_repo
@repo = ::Repository.find params[:id]
def find_project
@project = Project.find params[:project_id]
end
end

View File

@@ -1,25 +1,21 @@
class DevOps::CloudAccountsController < ApplicationController
before_action :require_login
before_action :find_project
before_action :devops_authorize!
def create
ActiveRecord::Base.transaction do
DevOps::CreateCloudAccountForm.new(devops_params).validate!
logger.info "######### devops_params: #{devops_params}"
logger.info "######### ......: #{(IPAddr.new devops_params[:ip_num]).to_i}"
logger.info "######### ......: #{DevOps::CloudAccount.encrypted_secret(devops_params[:secret])}"
# 1. 保存华为云服务器帐号
logger.info "######### ......ff: #{devops_params.merge(ip_num: IPAddr.new(devops_params[:ip_num]).to_i, secret: DevOps::CloudAccount.encrypted_secret(devops_params[:secret]))}"
create_params = devops_params.merge(ip_num: IPAddr.new(devops_params[:ip_num]).to_i, secret: DevOps::CloudAccount.encrypted_secret(devops_params[:secret]))
logger.info "######### create_params: #{create_params}"
if cloud_account = @repo.dev_ops_cloud_account
cloud_account
if cloud_account = @project.dev_ops_cloud_account
return render_error('该仓库已绑定了云帐号.')
else
cloud_account = DevOps::CloudAccount.new(create_params)
cloud_account.user = current_user
cloud_account.repo_id = @repo.id
cloud_account.repo_id = @project.repository.id
cloud_account.project_id = @project.id
cloud_account.save!
end
@@ -31,11 +27,12 @@ class DevOps::CloudAccountsController < ApplicationController
redirect_uri: gitea_oauth['redirect_uris'],
gitea_oauth_id: gitea_oauth['id'],
user_id: current_user.id,
project_id: devops_params[:project_id])
project_id: @project.id)
oauth.save
rpc_secret = SecureRandom.hex 16
logger.info "######### rpc_secret: #{rpc_secret}"
# 3. 创建drone server
drone_server_cmd = DevOps::Drone::Server.new(oauth.client_id, oauth.client_secret, cloud_account.drone_host, rpc_secret).generate_cmd
logger.info "######### drone_server_cmd: #{drone_server_cmd}"
@@ -49,12 +46,14 @@ class DevOps::CloudAccountsController < ApplicationController
logger.info "######### result: #{result}"
redirect_url = "#{Gitea.gitea_config[:domain]}/login/oauth/authorize?client_id=#{oauth.client_id}&redirect_uri=#{cloud_account.drone_url}/login&response_type=code"
redirect_url = "#{cloud_account.drone_url}/login"
logger.info "######### redirect_url: #{redirect_url}"
if result
if result && !result.blank?
render_ok(redirect_url: redirect_url)
else
render_error('激活失败')
render_error('激活失败, 请检查你的云服务器信息是否正确.')
raise ActiveRecord::Rollback
end
end
rescue Exception => ex
@@ -63,10 +62,10 @@ class DevOps::CloudAccountsController < ApplicationController
private
def devops_params
params.permit(:account, :secret, :ip_num, :repo_id)
params.permit(:account, :secret, :ip_num, :project_id)
end
def find_project
@repo = Repository.find params[:repo_id]
@project = Project.find params[:project_id]
end
end

View File

@@ -39,7 +39,7 @@ class DevOps::Drone::API < DevOps::Drone::Request
# Activate user's project with Drone CI
# POST api/repos/{owner}/{name}
# eq:
# DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.endpoint, project.owner.login, project.identifier).avtivate
# DevOps::Drone::API.new(cloud_account.drone_token, cloud_account.drone_url, project.owner.login, project.identifier).activate
def activate
post(endpoint, "/api/repos/#{owner}/#{repo}", drone_token: drone_token)
end

View File

@@ -11,23 +11,10 @@ class DevOps::Drone::Client
@rpc_secret = rpc_secret
end
def run
`docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DRONE_RPC_SERVER=drone-server-#{client_id}:9000 \
-e DRONE_RPC_SECRET=#{rpc_secret} \
-e DRONE_RUNNER_NAME=#{drone_ip} \
--restart always \
--name drone-agent--#{client_id} \
--net="bridge" \
drone/drone-runner-docker:1
`
end
def generate_cmd
"docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DRONE_RPC_SERVER=drone-server-#{client_id}:9000 \
-e DRONE_RPC_HOST=#{drone_ip}:80 \
-e DRONE_RPC_SECRET=#{rpc_secret} \
-e DRONE_RUNNER_NAME=#{drone_ip} \
--restart always \

View File

@@ -38,6 +38,11 @@
request(:put, endpoint, path, options)
end
def patch(endpoint, path, options={})
validate_request_params!(endpoint)
request(:patch, endpoint, path, options)
end
def delete(endpoint, path, options={})
validate_request_params!(endpoint)
request(:delete, endpoint, path, options)
@@ -45,10 +50,21 @@
private
def request(method, endpoint, path, **params)
Rails.logger.info("[drone] request: #{method} #{path} #{params.except(:secret).inspect}")
Rails.logger.info("[drone] request: #{method} #{path} #{params.except(:drone_token).inspect}")
client = Faraday.new(url: endpoint)
response = client.public_send(method, path, params)
client ||= begin
Faraday.new(url: endpoint) do |req|
req.request :url_encoded
req.headers['Content-Type'] = 'application/json'
req.response :logger # 显示日志
req.adapter Faraday.default_adapter
req.authorization :Bearer, params[:drone_token]
req.headers['Authorization']
end
end
response = client.public_send(method, path) do |req|
req.body = params.except(:drone_token).to_json
end
json_response(response)
end

View File

@@ -13,26 +13,6 @@ class DevOps::Drone::Server
@client_secret = client_secret
end
def run
`
docker run \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DRONE_GITEA_SERVER=#{gitea_url} \
-e DRONE_GITEA_CLIENT_ID=#{client_id} \
-e DRONE_GITEA_CLIENT_SECRET=#{client_secret} \
-e DRONE_RPC_SECRET=#{rpc_secret} \
-e DRONE_SERVER_HOST=#{drone_host} \
-e DRONE_SERVER_PROTO=http \
-p "80:80" \
-p "9000:9000" \
--restart=always \
--detach=true \
--name=drone-server-#{client_id} \
--net="bridge" \
drone/drone:1
`
end
# TODO 一下代码方便测试,正式环境请移除
# docker rm -f `docker ps -qa`
def generate_cmd
@@ -46,7 +26,6 @@ class DevOps::Drone::Server
-e DRONE_SERVER_HOST=#{drone_host} \
-e DRONE_SERVER_PROTO=http \
-p '80:80' \
-p '9000:9000' \
--restart=always \
--detach=true \
--name=drone-server-#{client_id} \