diff --git a/app/controllers/ci/base_controller.rb b/app/controllers/ci/base_controller.rb index 6f18db045..20a9cb15e 100644 --- a/app/controllers/ci/base_controller.rb +++ b/app/controllers/ci/base_controller.rb @@ -2,8 +2,7 @@ class Ci::BaseController < ApplicationController include Ci::DbConnectable before_action :require_login - before_action :connect_to_ci_database, if: -> { current_user && !current_user.is_a?(AnonymousUser) && !current_user.devops_uninit? } - before_action :connect_to_ci_database, only: :load_repo + before_action :connect_to_ci_db def load_repo namespace = params[:owner] @@ -45,4 +44,15 @@ class Ci::BaseController < ApplicationController @ci_user.blank? ? raise("未找到相关的记录") : @ci_user end + def connect_to_ci_db(options={}) + if !(current_user && !current_user.is_a?(AnonymousUser) && !current_user.devops_uninit?) + return + end + if current_user.ci_cloud_account.server_type == Ci::CloudAccount::SERVER_TYPE_TRUSTIE + connect_to_trustie_ci_database(options) + else + connect_to_ci_database(options) + end + end + end diff --git a/app/controllers/ci/cloud_accounts_controller.rb b/app/controllers/ci/cloud_accounts_controller.rb index a1429078e..2d2c83a1a 100644 --- a/app/controllers/ci/cloud_accounts_controller.rb +++ b/app/controllers/ci/cloud_accounts_controller.rb @@ -1,7 +1,7 @@ class Ci::CloudAccountsController < Ci::BaseController include Ci::CloudAccountManageable - skip_before_action :connect_to_ci_database, only: %i[create bind] + skip_before_action :connect_to_ci_db, only: %i[create bind trustie_bind] before_action :load_project, only: %i[create activate] before_action :authorize_owner!, only: %i[create activate] before_action :load_repo, only: %i[activate] @@ -73,6 +73,26 @@ class Ci::CloudAccountsController < Ci::BaseController render_error(ex.message) end + def trustie_bind + account = params[:account].to_s + return render_error("account不能为空.") if account.blank? + + flag, msg = check_trustie_bind_cloud_account! + return render_error(msg) if flag === true + + ActiveRecord::Base.transaction do + @cloud_account = trustie_bind_account! + if @cloud_account.blank? + render_error('激活失败, 请检查你的云服务器信息是否正确.') + raise ActiveRecord::Rollback + else + current_user.set_drone_step!(User::DEVOPS_UNVERIFIED) + end + end + rescue Exception => ex + render_error(ex.message) + end + def unbind ActiveRecord::Base.transaction do unbind_account! diff --git a/app/controllers/concerns/ci/cloud_account_manageable.rb b/app/controllers/concerns/ci/cloud_account_manageable.rb index 5931b31c9..ce60de3ba 100644 --- a/app/controllers/concerns/ci/cloud_account_manageable.rb +++ b/app/controllers/concerns/ci/cloud_account_manageable.rb @@ -4,9 +4,10 @@ module Ci::CloudAccountManageable included do end + # 自有服务器绑定流程 def bind_account! # 1. 保存华为云服务器帐号 - create_params = devops_params.merge(ip_num: IPAddr.new(devops_params[:ip_num].strip).to_i, secret: Ci::CloudAccount.encrypted_secret(devops_params[:secret])) + create_params = devops_params.merge(ip_num: IPAddr.new(devops_params[:ip_num].strip).to_i, secret: Ci::CloudAccount.encrypted_secret(devops_params[:secret]), server_type: Ci::CloudAccount::SERVER_TYPE_SELF) cloud_account = Ci::CloudAccount.new(create_params) cloud_account.user = current_user @@ -53,13 +54,45 @@ module Ci::CloudAccountManageable result && !result.blank? ? cloud_account : nil end + # trustie提供服务器,绑定流程 + def trustie_bind_account! + + # 读取drone配置信息 + config = Rails.application.config_for(:configuration).symbolize_keys! + trustie_drone_config = config[:trustie_drone].symbolize_keys! + raise 'trustie_drone config missing' if trustie_drone_config.blank? + + # 创建云账号 + create_params = devops_params.merge(ip_num: IPAddr.new(trustie_drone_config[:ip_num].strip).to_i, secret: Ci::CloudAccount.encrypted_secret(trustie_drone_config[:secret]), server_type: Ci::CloudAccount::SERVER_TYPE_TRUSTIE) + cloud_account = Ci::CloudAccount.new(create_params) + cloud_account.user = current_user + cloud_account.save! + + #生成oauth2应用程序的client_id和client_secrete + gitea_oauth = Gitea::Oauth2::CreateService.call(current_user.gitea_token, {name: "pipeline-#{SecureRandom.hex(8)}", redirect_uris: ["#{cloud_account.drone_url}/login"]}) + logger.info "######### gitea_oauth: #{gitea_oauth}" + oauth = Oauth.new(client_id: gitea_oauth['client_id'], + client_secret: gitea_oauth['client_secret'], + redirect_uri: gitea_oauth['redirect_uris'], + gitea_oauth_id: gitea_oauth['id'], + user_id: current_user.id) + result = oauth.save! + + redirect_url = "#{cloud_account.drone_url}/login" + logger.info "######### redirect_url: #{redirect_url}" + + return nil unless result.present? + result ? cloud_account : nil + end + def unbind_account! cloud_account = current_user.ci_cloud_account return render_error('你未绑定CI服务器') if current_user.devops_step == User::DEVOPS_UNINIT || cloud_account.blank? + if cloud_account.server_type == Ci::CloudAccount::SERVER_TYPE_SELF + @connection.execute("DROP DATABASE IF EXISTS #{current_user.login}_drone") # TOTO drop drone database + end cloud_account.destroy! unless cloud_account.blank? - @connection.execute("DROP DATABASE IF EXISTS #{current_user.login}_drone") # TOTO drop drone database - current_user.unbind_account! end @@ -84,6 +117,10 @@ module Ci::CloudAccountManageable Ci::CloudAccount.exists?(ip_num: ip_num) ? [true, "#{devops_params[:ip_num]}服务器已被使用."] : [false, nil] end + def check_trustie_bind_cloud_account! + return [true, "你已经绑定了云帐号."] unless current_user.ci_cloud_account.blank? + end + def gitea_auto_create_auth_grant!(gitea_oauth_id) connection = Gitea::Database.set_connection.connection unix_time = Time.now.to_i @@ -97,7 +134,6 @@ module Ci::CloudAccountManageable gitea_auto_create_auth_grant!(oauth&.gitea_oauth_id) state = SecureRandom.hex(8) - # redirect_uri eg: # https://localhost:3000/login/oauth/authorize?client_id=94976481-ad0e-4ed4-9247-7eef106007a2&redirect_uri=http%3A%2F%2F121.69.81.11%3A80%2Flogin&response_type=code&state=9cab990b9cfb1805 redirect_uri = CGI.escape("#{@cloud_account.drone_url}/login") diff --git a/app/controllers/concerns/ci/db_connectable.rb b/app/controllers/concerns/ci/db_connectable.rb index 2aaff87bf..559384a59 100644 --- a/app/controllers/concerns/ci/db_connectable.rb +++ b/app/controllers/concerns/ci/db_connectable.rb @@ -23,6 +23,24 @@ module Ci::DbConnectable @connection = Ci::Database.set_connection(db_params).connection end + def connect_to_trustie_ci_database(options={}) + master_db = options[:master_db] || false + config = Rails.application.config_for(:configuration).symbolize_keys! + db_config = config[:ci_db_server_trustie].symbolize_keys! + raise 'ci database config missing' if db_config.blank? + + req_params = { + host: db_config[:host], + username: db_config[:username], + password: db_config[:password], + port: db_config[:port] + } + + req_params = req_params.merge(database: "#{db_config[:database]}") unless master_db === true + db_params = Ci::Database.get_connection_params(req_params) + @trustie_db_connection = Ci::Database.set_connection(db_params).connection + end + def auto_create_database!(connection, database) Rails.logger.info "[CI::DbConnectable] auto_create_database's connection: #{connection}" connection.execute("CREATE DATABASE IF NOT EXISTS #{database}") diff --git a/app/libs/ci/drone/api.rb b/app/libs/ci/drone/api.rb index 6891efa93..1294fcb63 100644 --- a/app/libs/ci/drone/api.rb +++ b/app/libs/ci/drone/api.rb @@ -78,4 +78,10 @@ class Ci::Drone::API < Ci::Drone::Request def sync_repos post(endpoint, "/api/users/repos", drone_token: drone_token) end + + # Creates a user. + # POST /api/users + def create_user + post(endpoint, "/api/users", {login: options[:login], email: "admin@email.com", avatar_url:"",active:true, drone_token: options[:token]}) + end end diff --git a/app/models/ci/cloud_account.rb b/app/models/ci/cloud_account.rb index 253017dc5..2a63d6ee6 100644 --- a/app/models/ci/cloud_account.rb +++ b/app/models/ci/cloud_account.rb @@ -20,6 +20,10 @@ class Ci::CloudAccount < Ci::LocalBase belongs_to :user belongs_to :ci_user, class_name: 'Ci::User', foreign_key: :ci_user_id, optional: true + # server_type column: 0: 自有服务器;1: trustie提供服务器 + SERVER_TYPE_SELF = 0 + SERVER_TYPE_TRUSTIE = 1 + def drone_host [drone_ip, ":80"].join end diff --git a/app/views/ci/cloud_accounts/trustie_bind.json.jbuilder b/app/views/ci/cloud_accounts/trustie_bind.json.jbuilder new file mode 100644 index 000000000..cff42cefe --- /dev/null +++ b/app/views/ci/cloud_accounts/trustie_bind.json.jbuilder @@ -0,0 +1,8 @@ +json.step current_user.devops_step +json.cloud_account do + if @cloud_account && !current_user.devops_uninit? + json.ip @cloud_account.drone_ip + else + json.nil! + end +end diff --git a/config/routes.rb b/config/routes.rb index 145c20a7d..c6282581b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,5 @@ Rails.application.routes.draw do - + require 'sidekiq/web' require 'admin_constraint' @@ -162,6 +162,12 @@ Rails.application.routes.draw do as: :bind_cloud_acclount ) + post( + '/cloud_account/trustie_bind', + to: 'cloud_accounts#trustie_bind', + as: :trustie_bind_cloud_acclount + ) + get( '/cloud_account', to: 'cloud_accounts#show',