mirror of https://github.com/certd/certd
refactor: host
parent
991c3dbb76
commit
8122bed97f
|
@ -35,9 +35,13 @@ export class AbstractDnsProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccessProvider (accessProvider, accessProviders = this.accessProviders) {
|
getAccessProvider (accessProvider, accessProviders = this.accessProviders) {
|
||||||
|
let access = accessProvider
|
||||||
if (typeof accessProvider === 'string' && accessProviders) {
|
if (typeof accessProvider === 'string' && accessProviders) {
|
||||||
accessProvider = accessProviders[accessProvider]
|
access = accessProviders[accessProvider]
|
||||||
}
|
}
|
||||||
return accessProvider
|
if (access == null) {
|
||||||
|
throw new Error(`accessProvider :${accessProvider}不存在`)
|
||||||
|
}
|
||||||
|
return access
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ export class Executor {
|
||||||
options = _.merge(createDefaultOptions(), options)
|
options = _.merge(createDefaultOptions(), options)
|
||||||
return await this.doRun(options)
|
return await this.doRun(options)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('任务执行出错:' + e.message, e)
|
logger.error('任务执行出错', e)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ export class SshClient {
|
||||||
}
|
}
|
||||||
* @param transports
|
* @param transports
|
||||||
*/
|
*/
|
||||||
uploadFiles ({ connectConf, transports }) {
|
uploadFiles ({ connectConf, transports, sudo = false }) {
|
||||||
const conn = new ssh2.Client()
|
const conn = new ssh2.Client()
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -29,7 +29,8 @@ export class SshClient {
|
||||||
try {
|
try {
|
||||||
for (const transport of transports) {
|
for (const transport of transports) {
|
||||||
logger.info('上传文件:', JSON.stringify(transport))
|
logger.info('上传文件:', JSON.stringify(transport))
|
||||||
await this.exec({ connectConf, script: 'mkdir -p ' + path.dirname(transport.remotePath) })
|
sudo = sudo ? 'sudo' : ''
|
||||||
|
await this.exec({ connectConf, script: `${sudo} mkdir -p ${path.dirname(transport.remotePath)} ` })
|
||||||
await this.fastPut({ sftp, ...transport })
|
await this.fastPut({ sftp, ...transport })
|
||||||
}
|
}
|
||||||
resolve()
|
resolve()
|
||||||
|
@ -47,6 +48,7 @@ export class SshClient {
|
||||||
if (_.isArray(script)) {
|
if (_.isArray(script)) {
|
||||||
script = script.join('\n')
|
script = script.join('\n')
|
||||||
}
|
}
|
||||||
|
console.log('执行命令:', script)
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.connect({
|
this.connect({
|
||||||
connectConf,
|
connectConf,
|
||||||
|
@ -58,11 +60,12 @@ export class SshClient {
|
||||||
}
|
}
|
||||||
let data = null
|
let data = null
|
||||||
stream.on('close', (code, signal) => {
|
stream.on('close', (code, signal) => {
|
||||||
console.log(`[${connectConf.host}][close]:code:${code}, signal:${signal} `)
|
console.log(`[${connectConf.host}][close]:code:${code}`)
|
||||||
|
|
||||||
if (code === 0) {
|
|
||||||
data = data ? data.toString() : null
|
data = data ? data.toString() : null
|
||||||
|
if (code === 0) {
|
||||||
resolve(data)
|
resolve(data)
|
||||||
|
} else {
|
||||||
|
reject(new Error(data))
|
||||||
}
|
}
|
||||||
conn.end()
|
conn.end()
|
||||||
}).on('data', (ret) => {
|
}).on('data', (ret) => {
|
||||||
|
@ -70,8 +73,7 @@ export class SshClient {
|
||||||
data = ret
|
data = ret
|
||||||
}).stderr.on('data', (err) => {
|
}).stderr.on('data', (err) => {
|
||||||
console.log(`[${connectConf.host}][error]: ` + err)
|
console.log(`[${connectConf.host}][error]: ` + err)
|
||||||
reject(new Error(err.toString()))
|
data = err
|
||||||
stream.close()
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,9 @@ export class UploadCertToHost extends AbstractHostPlugin {
|
||||||
filter: 'ssh'
|
filter: 'ssh'
|
||||||
},
|
},
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
sudo: {
|
||||||
|
label: '是否sudo'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
|
@ -45,7 +48,6 @@ export class UploadCertToHost extends AbstractHostPlugin {
|
||||||
async execute ({ cert, props, context }) {
|
async execute ({ cert, props, context }) {
|
||||||
const { crtPath, keyPath, accessProvider } = props
|
const { crtPath, keyPath, accessProvider } = props
|
||||||
const connectConf = this.getAccessProvider(accessProvider)
|
const connectConf = this.getAccessProvider(accessProvider)
|
||||||
console.log('connectConf', connectConf)
|
|
||||||
const sshClient = new SshClient()
|
const sshClient = new SshClient()
|
||||||
await sshClient.uploadFiles({
|
await sshClient.uploadFiles({
|
||||||
connectConf,
|
connectConf,
|
||||||
|
|
|
@ -22,7 +22,18 @@ describe('HostShellExecute', function () {
|
||||||
const ret = await plugin.doExecute(uploadOpts)
|
const ret = await plugin.doExecute(uploadOpts)
|
||||||
expect(ret).ok
|
expect(ret).ok
|
||||||
console.log('-----' + JSON.stringify(ret))
|
console.log('-----' + JSON.stringify(ret))
|
||||||
|
})
|
||||||
|
|
||||||
await plugin.doRollback(uploadOpts)
|
it('#execute-hk-restart-docker', async function () {
|
||||||
|
this.timeout(10000)
|
||||||
|
const options = createOptions()
|
||||||
|
const plugin = new HostShellExecute(options)
|
||||||
|
const uploadOpts = {
|
||||||
|
props: { script: ['cd /home/ubuntu/deloy/nginx-proxy\nsudo docker-compose build\nsudo docker-compose up -d\n'], accessProvider: 'aliyun-ssh-hk' },
|
||||||
|
context: {}
|
||||||
|
}
|
||||||
|
const ret = await plugin.doExecute(uploadOpts)
|
||||||
|
expect(ret).ok
|
||||||
|
console.log('-----' + JSON.stringify(ret))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,4 +24,25 @@ describe('PluginUploadToHost', function () {
|
||||||
|
|
||||||
await plugin.doRollback(uploadOpts)
|
await plugin.doRollback(uploadOpts)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('#execute-to-ubantu', async function () {
|
||||||
|
this.timeout(10000)
|
||||||
|
const options = createOptions()
|
||||||
|
options.args = { test: false }
|
||||||
|
options.cert.email = 'xiaojunnuo@qq.com'
|
||||||
|
options.cert.domains = ['*.docmirror.cn']
|
||||||
|
const plugin = new UploadCertToHost(options)
|
||||||
|
const certd = new Certd(options)
|
||||||
|
const cert = await certd.readCurrentCert()
|
||||||
|
const context = {}
|
||||||
|
const uploadOpts = {
|
||||||
|
cert,
|
||||||
|
props: { crtPath: '/home/ubuntu/deloy/nginx-proxy/ssl/test.crt', keyPath: '/home/ubuntu/deloy/nginx-proxy/ssl/test.key', accessProvider: 'aliyun-ssh-hk' },
|
||||||
|
context
|
||||||
|
}
|
||||||
|
await plugin.doExecute(uploadOpts)
|
||||||
|
console.log('context:', context)
|
||||||
|
|
||||||
|
await plugin.doRollback(uploadOpts)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -33,6 +33,9 @@ export default {
|
||||||
|
|
||||||
const templatePkg = require('../templates/certd-run/package.json')
|
const templatePkg = require('../templates/certd-run/package.json')
|
||||||
templatePkg.dependencies['@certd/executor'] = '^' + currentVersion
|
templatePkg.dependencies['@certd/executor'] = '^' + currentVersion
|
||||||
|
templatePkg.dependencies['@certd/plugin-aliyun'] = '^' + currentVersion
|
||||||
|
templatePkg.dependencies['@certd/plugin-host'] = '^' + currentVersion
|
||||||
|
templatePkg.dependencies['@certd/plugin-tencent'] = '^' + currentVersion
|
||||||
const pkgFilePath = path.join(targetProjectDir, 'package.json')
|
const pkgFilePath = path.join(targetProjectDir, 'package.json')
|
||||||
fs.writeJsonSync(pkgFilePath, templatePkg)
|
fs.writeJsonSync(pkgFilePath, templatePkg)
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,17 @@ import { Executor } from '@certd/executor'
|
||||||
import PluginAliyun from '@certd/plugin-aliyun'
|
import PluginAliyun from '@certd/plugin-aliyun'
|
||||||
import PluginTencent from '@certd/plugin-tencent'
|
import PluginTencent from '@certd/plugin-tencent'
|
||||||
import PluginHost from '@certd/plugin-host'
|
import PluginHost from '@certd/plugin-host'
|
||||||
import options from './options.json'
|
|
||||||
|
|
||||||
// 安装默认插件和授权提供者
|
// 安装默认插件和授权提供者
|
||||||
PluginAliyun.install()
|
PluginAliyun.install()
|
||||||
PluginTencent.install()
|
PluginTencent.install()
|
||||||
PluginHost.install()
|
PluginHost.install()
|
||||||
|
|
||||||
|
// import options
|
||||||
|
import { createRequire } from 'module'
|
||||||
|
const require = createRequire(import.meta.url)
|
||||||
|
const options =require('./options.json')
|
||||||
|
|
||||||
|
//开始执行
|
||||||
const executor = new Executor()
|
const executor = new Executor()
|
||||||
executor.run(options)
|
await executor.run(options)
|
||||||
|
|
Loading…
Reference in New Issue