refactor: ui prepare

master
xiaojunnuo 2021-01-21 23:59:06 +08:00
parent c26417d769
commit d3619ad60f
17 changed files with 292 additions and 245 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@ out
gen
node_modules/
/test/*.private.*
/other
/other/node-acme-client/.idea/
/*.log
/other/certd-run

View File

@ -1,6 +1,7 @@
{
"packages": [
"packages/*"
"packages/*",
"other/*"
],
"version": "0.1.11"
}

View File

@ -0,0 +1,9 @@
import { request } from './service'
export default {
list () {
return request({
url: '/plugins/list'
})
}
}

View File

@ -0,0 +1,9 @@
export default {
devServer: {
proxy: {
'/': {
target: 'http://localhost:3000/'
}
}
}
}

View File

@ -0,0 +1,34 @@
import _ from 'lodash-es'
import logger from '../utils/util.log.js'
export class AbstractDnsProvider {
constructor () {
this.logger = logger
}
async createRecord ({ fullRecord, type, value }) {
throw new Error('请实现 createRecord 方法')
}
async removeRecord ({ fullRecord, type, value, record }) {
throw new Error('请实现 removeRecord 方法')
}
async getDomainList () {
throw new Error('请实现 getDomainList 方法')
}
async matchDomain (dnsRecord, domainPropName) {
const list = await this.getDomainList()
let domain = null
for (const item of list) {
if (_.endsWith(dnsRecord, item[domainPropName])) {
domain = item
break
}
}
if (!domain) {
throw new Error('找不到域名,请检查域名是否正确:' + dnsRecord)
}
return domain
}
}

View File

@ -1,34 +1,2 @@
import _ from 'lodash-es'
import logger from '../utils/util.log.js'
export class AbstractDnsProvider {
constructor () {
this.logger = logger
}
async createRecord ({ fullRecord, type, value }) {
throw new Error('请实现 createRecord 方法')
}
async removeRecord ({ fullRecord, type, value, record }) {
throw new Error('请实现 removeRecord 方法')
}
async getDomainList () {
throw new Error('请实现 getDomainList 方法')
}
async matchDomain (dnsRecord, domainPropName) {
const list = await this.getDomainList()
let domain = null
for (const item of list) {
if (_.endsWith(dnsRecord, item[domainPropName])) {
domain = item
break
}
}
if (!domain) {
throw new Error('找不到域名,请检查域名是否正确:' + dnsRecord)
}
return domain
}
}
export { providerRegistry } from './provider-registry.js'
export { AbstractDnsProvider } from './abstract-provider.js'

View File

@ -0,0 +1,26 @@
export class ProviderRegistry {
constructor () {
this.providers = {}
}
install (provider) {
if (provider == null) {
return
}
if (this.providers == null) {
this.providers = {}
}
const name = provider.name || (provider.define && provider.define.name)
this.providers[name] = provider
}
get (name) {
if (name) {
return this.providers[name]
}
throw new Error(`找不到授权提供者:${name}`)
}
}
export const providerRegistry = new ProviderRegistry()

View File

@ -1,4 +1,4 @@
export { AbstractDnsProvider } from './dns-provider/index.js'
export * from './dns-provider/index.js'
export * from './plugin/index.js'
export { Store } from './store/store.js'
export { util } from './utils/index.js'
export { AbstractPlugin } from './plugin/index.js'

View File

@ -0,0 +1,75 @@
import fs from 'fs'
import logger from '../utils/util.log.js'
import dayjs from 'dayjs'
import Sleep from '../utils/util.sleep.js'
import { pluginRegistry } from './plugin-registry.js'
export class AbstractPlugin {
constructor ({ accessProviders }) {
this.logger = logger
this.accessProviders = accessProviders
}
appendTimeSuffix (name) {
if (name == null) {
name = 'certd'
}
return name + '-' + dayjs().format('YYYYMMDD-HHmmss')
}
async executeFromContextFile (options = {}) {
const { contextPath } = options
const contextJson = fs.readFileSync(contextPath)
const context = JSON.parse(contextJson)
options.context = context
await this.doExecute(options)
fs.writeFileSync(JSON.stringify(context))
}
async doExecute (options) {
try {
return await this.execute(options)
} catch (e) {
logger.error('插件执行出错:', e)
throw e
}
}
/**
* 执行
* @param options
* @returns {Promise<void>}
*/
async execute (options) {
console.error('请实现此方法,context:', options.context)
}
async doRollback (options) {
try {
return await this.rollback(options)
} catch (e) {
logger.error('插件rollback出错', e)
throw e
}
}
/**
* 回退如有必要
* @param options
*/
async rollback (options) {
console.error('请实现此方法,rollback:', options.context)
}
getAccessProvider (accessProvider, accessProviders = this.accessProviders) {
if (typeof accessProvider === 'string' && accessProviders) {
accessProvider = accessProviders[accessProvider]
}
return accessProvider
}
async sleep (time) {
await Sleep(time)
}
}

View File

@ -1,72 +1,2 @@
import fs from 'fs'
import logger from '../utils/util.log.js'
import dayjs from 'dayjs'
import Sleep from '../utils/util.sleep.js'
export class AbstractPlugin {
constructor ({ accessProviders }) {
this.logger = logger
this.accessProviders = accessProviders
}
appendTimeSuffix (name) {
if (name == null) {
name = 'certd'
}
return name + '-' + dayjs().format('YYYYMMDD-HHmmss')
}
async executeFromContextFile (options = {}) {
const { contextPath } = options
const contextJson = fs.readFileSync(contextPath)
const context = JSON.parse(contextJson)
options.context = context
await this.doExecute(options)
fs.writeFileSync(JSON.stringify(context))
}
async doExecute (options) {
try {
return await this.execute(options)
} catch (e) {
logger.error('插件执行出错:', e)
throw e
}
}
/**
* 执行
* @param options
* @returns {Promise<void>}
*/
async execute (options) {
console.error('请实现此方法,context:', options.context)
}
async doRollback (options) {
try {
return await this.rollback(options)
} catch (e) {
logger.error('插件rollback出错', e)
throw e
}
}
/**
* 回退如有必要
* @param options
*/
async rollback (options) {
console.error('请实现此方法,rollback:', options.context)
}
getAccessProvider (accessProvider, accessProviders = this.accessProviders) {
if (typeof accessProvider === 'string' && accessProviders) {
accessProvider = accessProviders[accessProvider]
}
return accessProvider
}
async sleep (time) {
await Sleep(time)
}
}
export { pluginRegistry } from './plugin-registry.js'
export { AbstractPlugin } from './abstract-plugin.js'

View File

@ -0,0 +1,27 @@
export class PluginRegistry {
constructor () {
this.plugins = {}
}
install (plugin) {
if (plugin == null) {
return
}
if (this.plugins == null) {
this.plugins = {}
}
const name = plugin.name || (plugin.define && plugin.define.name)
this.plugins[name] = plugin
}
get (name) {
if (name) {
return this.plugins[name]
}
throw new Error(`找不到${name}插件`)
}
}
export const pluginRegistry = new PluginRegistry()

View File

@ -1,27 +1,12 @@
import { util, Store } from '@certd/api'
import { util, Store, pluginRegistry } from '@certd/api'
import { AcmeService } from './acme.js'
import { FileStore } from './store/file-store.js'
import { CertStore } from './store/cert-store.js'
import dayjs from 'dayjs'
import forge from 'node-forge'
import DefaultProviders from '@certd/providers'
import _ from 'lodash-es'
const logger = util.logger
const AccessProviderClasses = {}
function install (providerClass) {
AccessProviderClasses[providerClass.name()] = providerClass
}
logger.info('use')
_.forEach(DefaultProviders, item => {
logger.info('use:', item.name())
install(item)
})
export class Certd {
static use (providerClass) {
install(providerClass)
}
constructor (options) {
this.options = options
this.email = options.cert.email
@ -139,7 +124,7 @@ export class Certd {
createProviderByType (type, options) {
try {
const Provider = AccessProviderClasses[type]
const Provider = pluginRegistry.get(type)
return new Provider(options)
} catch (e) {
throw new Error('暂不支持此dnsProvider,请先use该provider' + type, e)

View File

@ -1,11 +1,16 @@
import { Certd } from '@certd/certd'
import DefaultPlugins from '@certd/plugins'
import { util } from '@certd/api'
import { pluginRegistry, util } from '@certd/api'
import _ from 'lodash-es'
import dayjs from 'dayjs'
import { Trace } from './trace.js'
import DefaultPlugins from '@certd/plugins'
import DefaultProviders from '@certd/providers'
const logger = util.logger
// 安装默认插件和授权提供者
DefaultPlugins.install()
DefaultProviders.install()
function createDefaultOptions () {
return {
args: {
@ -18,44 +23,9 @@ function createDefaultOptions () {
}
export class Executor {
constructor () {
this.usePlugins(DefaultPlugins)
this.trace = new Trace()
}
useProviders (providers) {
if (providers) {
_.forEach(item => {
Certd.use(item)
})
}
}
useProvider (provider) {
Certd.use(provider)
}
usePlugin (plugin) {
if (plugin == null) {
return
}
if (this.plugins == null) {
this.plugins = {}
}
this.plugins[plugin.name] = plugin
if (plugin.define) {
const define = plugin.define()
this.plugins[define.name] = plugin
}
}
usePlugins (plugins) {
if (plugins) {
_.forEach(plugins, item => {
this.usePlugin(item)
})
}
}
async run (options) {
logger.info('------------------- Cert-D ---------------------')
try {
@ -70,7 +40,7 @@ export class Executor {
async doRun (options) {
// 申请证书
logger.info('任务开始')
const certd = new Certd(options, this.providers)
const certd = new Certd(options)
const cert = await this.runCertd(certd)
if (cert == null) {
throw new Error('申请证书失败')
@ -165,7 +135,7 @@ export class Executor {
async runTask ({ options, task, cert, context, deploy, trace }) {
const taskType = task.type
const Plugin = this.plugins[taskType]
const Plugin = pluginRegistry.get(taskType)
const deployName = deploy.deployName
const taskName = task.taskName
if (Plugin == null) {

View File

@ -1,15 +1,8 @@
import { AbstractAliyunPlugin } from '../../aliyun/abstract-aliyun.js'
import Core from '@alicloud/pop-core'
import dayjs from 'dayjs'
export class DeployCertToAliyunCDN extends AbstractAliyunPlugin {
/**
* 插件定义
* 名称
* 入参
* 出参
*/
static define () {
return {
const define = {
name: 'deployCertToAliyunCDN',
label: '部署到阿里云CDN',
input: {
@ -48,7 +41,11 @@ export class DeployCertToAliyunCDN extends AbstractAliyunPlugin {
output: {
}
}
}
export class DeployCertToAliyunCDN extends AbstractAliyunPlugin {
static define () {
return define
}
async execute ({ cert, props, context }) {

View File

@ -1,14 +1,7 @@
import Core from '@alicloud/pop-core'
import { AbstractAliyunPlugin } from '../abstract-aliyun.js'
export class UploadCertToAliyun extends AbstractAliyunPlugin {
/**
* 插件定义
* 名称
* 入参
* 出参
*/
static define () {
return {
const define = {
name: 'uploadCertToAliyun',
label: '上传证书到阿里云',
input: {
@ -32,7 +25,11 @@ export class UploadCertToAliyun extends AbstractAliyunPlugin {
desc: '上传成功后的阿里云CertId'
}
}
}
}
export class UploadCertToAliyun extends AbstractAliyunPlugin {
static define () {
return define
}
getClient (aliyunProvider) {

View File

@ -1,3 +1,4 @@
import _ from 'lodash-es'
import { UploadCertToAliyun } from './aliyun/upload-to-aliyun/index.js'
import { DeployCertToAliyunCDN } from './aliyun/deploy-to-cdn/index.js'
@ -8,8 +9,9 @@ import { DeployCertToTencentCDN } from './tencent/deploy-to-cdn/index.js'
import { DeployCertToTencentCLB } from './tencent/deploy-to-clb/index.js'
import { DeployCertToTencentTKEIngress } from './tencent/deploy-to-tke-ingress/index.js'
import { pluginRegistry } from '@certd/api'
export default {
export const DefaultPlugins = {
UploadCertToAliyun,
DeployCertToAliyunCDN,
UploadCertToTencent,
@ -17,3 +19,10 @@ export default {
DeployCertToTencentCDN,
DeployCertToTencentCLB
}
export default {
install () {
_.forEach(DefaultPlugins, item => {
pluginRegistry.install(item)
})
}
}

View File

@ -1,7 +1,16 @@
import _ from 'lodash-es'
import { AliyunDnsProvider } from './dns-provider/aliyun.js'
import { DnspodDnsProvider } from './dns-provider/dnspod.js'
import { providerRegistry } from '@certd/api'
export default {
export const DefaultProviders = {
AliyunDnsProvider,
DnspodDnsProvider
}
export default {
install () {
_.forEach(DefaultProviders, item => {
providerRegistry.install(item)
})
}
}