mirror of https://github.com/certd/certd
feat: deployFlow
parent
a4bd29e6bf
commit
06603759fd
|
@ -4,4 +4,4 @@
|
|||
out
|
||||
gen
|
||||
node_modules/
|
||||
packages/*/test/*-private.js
|
||||
packages/*/test/*.private.js
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"packages": [
|
||||
"packages/deploy/*",
|
||||
"packages/*"
|
||||
],
|
||||
"version": "0.0.0"
|
||||
"version": "0.0.1"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "certd",
|
||||
"version": "1.0.0",
|
||||
"name": "@certd/certd",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "src/index.js",
|
||||
"exports": "src/index.js",
|
||||
|
@ -12,13 +12,14 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@types/node": "^14.14.13",
|
||||
"acme-client": "^4.1.2",
|
||||
"chai": "^4.2.0",
|
||||
"dayjs": "^1.9.7",
|
||||
"lodash": "^4.17.20",
|
||||
"log4js": "^6.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"eslint": "^7.15.0",
|
||||
"eslint-config-standard": "^16.0.2",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
|
|
|
@ -9,9 +9,10 @@ import util from './utils/util.js'
|
|||
import forge from 'node-forge'
|
||||
process.env.DEBUG = '*'
|
||||
export class Certd {
|
||||
constructor () {
|
||||
constructor (options) {
|
||||
this.store = new FileStore()
|
||||
this.acme = new AcmeService(this.store)
|
||||
this.options = options
|
||||
}
|
||||
|
||||
buildCertDir (email, domains) {
|
||||
|
@ -22,6 +23,9 @@ export class Certd {
|
|||
}
|
||||
|
||||
async certApply (options) {
|
||||
if (options == null) {
|
||||
options = this.options
|
||||
}
|
||||
const certOptions = options.cert
|
||||
const providers = options.providers
|
||||
const providerOptions = providers[certOptions.challenge.dnsProvider]
|
||||
|
|
|
@ -20,7 +20,9 @@ describe('Certd', function () {
|
|||
const cert = await certd.certApply(options)
|
||||
expect(cert).ok
|
||||
expect(cert.crt).ok
|
||||
expect(cert.key).to.be.ok
|
||||
expect(cert.key).ok
|
||||
expect(cert.detail).ok
|
||||
expect(cert.expires).ok
|
||||
})
|
||||
|
||||
it('#readCurrentCert', async function () {
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
||||
|
||||
"@types/node@^14":
|
||||
"@types/node@^14", "@types/node@^14.14.13":
|
||||
version "14.14.13"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-14.14.13.tgz#9e425079799322113ae8477297ae6ef51b8e0cdf"
|
||||
integrity sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"extends": "standard",
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.test.js", "*.spec.js"],
|
||||
"rules": {
|
||||
"no-unused-expressions": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "@certd/samples",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@types/node": "^14.14.13",
|
||||
"lodash": "^4.17.20",
|
||||
"log4js": "^6.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"eslint": "^7.15.0",
|
||||
"eslint-config-standard": "^16.0.2",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"mocha": "^8.2.1"
|
||||
},
|
||||
"author": "Greper",
|
||||
"license": "MIT"
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import Certd from '@certd/certd'
|
||||
import CertdPlugins from '@certd/plugins'
|
||||
import options from './options'
|
||||
import log from './util.log'
|
||||
export class DeployFlow {
|
||||
async run () {
|
||||
const certd = new Certd()
|
||||
const cert = certd.certApply(options)
|
||||
for (const deploy of options.deploy) {
|
||||
log.info(`-------部署任务【${deploy.deployName}】开始-------`)
|
||||
|
||||
for (const task of deploy.tasks) {
|
||||
await this.runTask({ options, cert, task })
|
||||
}
|
||||
log.info(`-------部署任务【${deploy.deployName}】完成-------`)
|
||||
}
|
||||
}
|
||||
|
||||
async runTask ({ options, task, cert }) {
|
||||
const taskType = task.type
|
||||
const plugin = CertdPlugins[taskType]
|
||||
if (plugin == null) {
|
||||
throw new Error(`插件:${taskType}还未安装`)
|
||||
}
|
||||
const context = {}
|
||||
log.info(`--插件【${task.taskName}】开始执行-------`)
|
||||
await plugin.execute({ cert, providers: options.providers, args: task, context })
|
||||
log.info(`--插件【${task.taskName}】执行完成-------`)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import util from './util.js'
|
||||
import log4js from 'log4js'
|
||||
import path from 'path'
|
||||
const level = process.env.NODE_ENV === 'development' ? 'debug' : 'info'
|
||||
const filename = path.join(util.getUserBasePath(), '/logs/certd.log')
|
||||
log4js.configure({
|
||||
appenders: { std: { type: 'stdout' }, file: { type: 'file', pattern: 'yyyy-MM-dd', daysToKeep: 3, filename } },
|
||||
categories: { default: { appenders: ['std'], level: level } }
|
||||
})
|
||||
const logger = log4js.getLogger('certd')
|
||||
export default logger
|
|
@ -0,0 +1,87 @@
|
|||
import _ from 'lodash'
|
||||
import optionsPrivate from './options.private.js'
|
||||
const defaultOptions = {
|
||||
providers: {
|
||||
aliyun: {
|
||||
providerType: 'aliyun',
|
||||
accessKeyId: '',
|
||||
accessKeySecret: ''
|
||||
},
|
||||
myLinux: {
|
||||
providerType: 'SSH',
|
||||
username: 'xxx',
|
||||
password: 'xxx',
|
||||
host: '1111.com',
|
||||
port: 22,
|
||||
publicKey: ''
|
||||
}
|
||||
},
|
||||
cert: {
|
||||
domains: ['*.docmirror.club', 'docmirror.club'],
|
||||
email: 'xiaojunnuo@qq.com',
|
||||
challenge: {
|
||||
challengeType: 'dns',
|
||||
dnsProvider: 'aliyun'
|
||||
},
|
||||
csrInfo: {
|
||||
country: 'CN',
|
||||
state: 'GuangDong',
|
||||
locality: 'ShengZhen',
|
||||
organization: 'CertD Org.',
|
||||
organizationUnit: 'IT Department',
|
||||
emailAddress: 'xiaojunnuo@qq.com'
|
||||
}
|
||||
},
|
||||
deploy: [
|
||||
{
|
||||
deployName: '流程1-部署到阿里云系列产品',
|
||||
tasks: [
|
||||
{
|
||||
name: '上传证书到云',
|
||||
taskType: 'uploadCertToCloud',
|
||||
certStore: 'aliyun'
|
||||
},
|
||||
{
|
||||
name: '部署证书到SLB',
|
||||
taskType: 'deployCertToAliyunSLB',
|
||||
certStore: 'aliyun'
|
||||
},
|
||||
{
|
||||
name: '部署证书到阿里云集群Ingress',
|
||||
taskType: 'deployCertToAliyunK8sIngress',
|
||||
certStore: 'aliyun'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
deployName: '流程2-部署到nginx服务器',
|
||||
tasks: [
|
||||
{
|
||||
name: '上传证书到服务器,并重启nginx',
|
||||
taskType: 'sshAndExecute',
|
||||
ssh: 'myLinux',
|
||||
upload: [
|
||||
{ from: '{certPath}', to: '/xxx/xxx/xxx.cert.pem' },
|
||||
{ from: '{keyPath}', to: '/xxx/xxx/xxx.key' }
|
||||
],
|
||||
script: 'sudo systemctl restart nginx'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
deployName: '流程3-触发jenkins任务',
|
||||
tasks: [
|
||||
{
|
||||
name: '触发jenkins任务',
|
||||
taskType: 'sshAndExecute',
|
||||
ssh: 'myLinux',
|
||||
script: 'sudo systemctl restart nginx'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
_.merge(defaultOptions, optionsPrivate)
|
||||
|
||||
export default defaultOptions
|
|
@ -0,0 +1,64 @@
|
|||
Arguments:
|
||||
D:\Soft\Development\Nodejs\node.exe C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\bin\yarn.js install
|
||||
|
||||
PATH:
|
||||
D:\Code\certd\certd\node_modules\.bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\libnvvp;D:\Soft\Development\Python3.5.3\Scripts\;D:\Soft\Development\Python3.5.3\;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64;C:\Program Files\Anaconda3;C:\Program Files\Anaconda3\Scripts;C:\Program Files\Anaconda3\Library\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;D:\Soft\Development\Zookeeper\bin;D:\Soft\Development\Maven\apache-maven-3.0.3\bin;C:\WINDOWS\System32\OpenSSH\;D:\Soft\Development\Microsoft VS Code\bin;D:\Soft\Development\Redis\;D:\Soft\Development\gradle-4.10.3\bin;D:\Soft\Development\Android\flutter\bin;C:\Program Files (x86)\QT Lite\QTSystem;D:\Soft\Development\java\bin;C:\ProgramData;D:\Soft\Development\nvmnodejs;D:\Soft\Development\Git\cmd;D:\Soft\Development\Go\bin;D:\Code\open\fgit-go\release;D:\Soft\Development\Nodejs\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;D:\Soft\Development\Microsoft VS Code\bin;D:\Soft\Development\IntelliJ IDEA 2018.3.2\bin;C:\Users\Administrator\AppData\Local\BypassRuntm;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;D:\Soft\Development\IntelliJ IDEA 2020.2\bin;;C:\Users\Administrator\AppData\Local\GitHubDesktop\bin;C:\Users\Administrator\go\bin;D:\Resources\npm\global;D:\Resources\yarn\global;C:\Users\Administrator\AppData\Roaming\npm;
|
||||
|
||||
Yarn version:
|
||||
1.22.10
|
||||
|
||||
Node version:
|
||||
14.15.0
|
||||
|
||||
Platform:
|
||||
win32 x64
|
||||
|
||||
Trace:
|
||||
Error: https://registry.npmjs.org/@certd%2fcertd: Not found
|
||||
at Request.params.callback [as _callback] (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:66988:18)
|
||||
at Request.self.callback (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:140662:22)
|
||||
at Request.emit (events.js:315:20)
|
||||
at Request.<anonymous> (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:141634:10)
|
||||
at Request.emit (events.js:315:20)
|
||||
at IncomingMessage.<anonymous> (C:\Users\Administrator\AppData\Roaming\npm\node_modules\yarn\lib\cli.js:141556:12)
|
||||
at Object.onceWrapper (events.js:421:28)
|
||||
at IncomingMessage.emit (events.js:327:22)
|
||||
at endReadableNT (_stream_readable.js:1327:12)
|
||||
at processTicksAndRejections (internal/process/task_queues.js:80:21)
|
||||
|
||||
npm manifest:
|
||||
{
|
||||
"name": "@certd/samples",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@types/node": "^14.14.13",
|
||||
"lodash": "^4.17.20",
|
||||
"log4js": "^6.3.0",
|
||||
"@certd/certd": "^0.0.1",
|
||||
"@certd/plugins": "^0.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"eslint": "^7.15.0",
|
||||
"eslint-config-standard": "^16.0.2",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"mocha": "^8.2.1"
|
||||
},
|
||||
"author": "Greper",
|
||||
"license": "MIT"
|
||||
}
|
||||
|
||||
yarn manifest:
|
||||
No manifest
|
||||
|
||||
Lockfile:
|
||||
No lockfile
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"extends": "standard",
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.test.js", "*.spec.js"],
|
||||
"rules": {
|
||||
"no-unused-expressions": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "@certd/plugins",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@types/node": "^14.14.13",
|
||||
"lodash": "^4.17.20",
|
||||
"log4js": "^6.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"eslint": "^7.15.0",
|
||||
"eslint-config-standard": "^16.0.2",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"mocha": "^8.2.1"
|
||||
},
|
||||
"author": "Greper",
|
||||
"license": "MIT"
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import fs from 'fs'
|
||||
export class AbstractPlugin {
|
||||
async executeFromContextFile (options = {}) {
|
||||
const { contextPath } = options
|
||||
const contextJson = fs.readFileSync(contextPath)
|
||||
const context = JSON.parse(contextJson)
|
||||
const newContext = await this.execute(options, context)
|
||||
fs.writeFileSync(JSON.stringify(newContext || context))
|
||||
}
|
||||
|
||||
async execute (options, context) {
|
||||
console.log('请实现此方法,context:', context)
|
||||
return context
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
import { UploadCertToAliyun } from './upload/upload-cert-to-aliyun/index.js'
|
||||
export default {
|
||||
UploadCertToAliyun
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import { AbstractPlugin } from '../../abstract-plugin/index.js'
|
||||
import Core from '@alicloud/pop-core'
|
||||
import dayjs from 'dayjs'
|
||||
export class UploadCertToAliyunPlugin extends AbstractPlugin {
|
||||
getClient (aliyunProvider) {
|
||||
this.client = new Core({
|
||||
accessKeyId: aliyunProvider.accessKeyId,
|
||||
accessKeySecret: aliyunProvider.accessKeySecret,
|
||||
endpoint: 'https://alidns.aliyuncs.com',
|
||||
apiVersion: '2015-01-09'
|
||||
})
|
||||
}
|
||||
|
||||
async execute ({ providers, cert, args, context }) {
|
||||
const { name, provider } = args
|
||||
const certName = name + '-' + dayjs().format('YYYYMMDDHHmmss')
|
||||
const params = {
|
||||
RegionId: 'cn-hangzhou',
|
||||
Name: certName,
|
||||
Cert: cert.crt.toString(),
|
||||
Key: cert.key.toString()
|
||||
}
|
||||
|
||||
const requestOption = {
|
||||
method: 'POST'
|
||||
}
|
||||
|
||||
const client = this.getClient(providers[provider])
|
||||
const ret = await client.request('CreateUserCertificate', params, requestOption)
|
||||
|
||||
context.AliyunCertId = ret.CertId
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import util from './util.js'
|
||||
import log4js from 'log4js'
|
||||
import path from 'path'
|
||||
const level = process.env.NODE_ENV === 'development' ? 'debug' : 'info'
|
||||
const filename = path.join(util.getUserBasePath(), '/logs/certd.log')
|
||||
log4js.configure({
|
||||
appenders: { std: { type: 'stdout' }, file: { type: 'file', pattern: 'yyyy-MM-dd', daysToKeep: 3, filename } },
|
||||
categories: { default: { appenders: ['file', 'std'], level: level } }
|
||||
})
|
||||
const logger = log4js.getLogger('certd')
|
||||
export default logger
|
|
@ -0,0 +1,87 @@
|
|||
import _ from 'lodash'
|
||||
import optionsPrivate from './options.private.js'
|
||||
const defaultOptions = {
|
||||
providers: {
|
||||
aliyun: {
|
||||
providerType: 'aliyun',
|
||||
accessKeyId: '',
|
||||
accessKeySecret: ''
|
||||
},
|
||||
myLinux: {
|
||||
providerType: 'SSH',
|
||||
username: 'xxx',
|
||||
password: 'xxx',
|
||||
host: '1111.com',
|
||||
port: 22,
|
||||
publicKey: ''
|
||||
}
|
||||
},
|
||||
cert: {
|
||||
domains: ['*.docmirror.club', 'docmirror.club'],
|
||||
email: 'xiaojunnuo@qq.com',
|
||||
challenge: {
|
||||
challengeType: 'dns',
|
||||
dnsProvider: 'aliyun'
|
||||
},
|
||||
csrInfo: {
|
||||
country: 'CN',
|
||||
state: 'GuangDong',
|
||||
locality: 'ShengZhen',
|
||||
organization: 'CertD Org.',
|
||||
organizationUnit: 'IT Department',
|
||||
emailAddress: 'xiaojunnuo@qq.com'
|
||||
}
|
||||
},
|
||||
deploy: [
|
||||
{
|
||||
deployName: '流程1-部署到阿里云系列产品',
|
||||
tasks: [
|
||||
{
|
||||
name: '上传证书到云',
|
||||
taskType: 'uploadCertToCloud',
|
||||
certStore: 'aliyun'
|
||||
},
|
||||
{
|
||||
name: '部署证书到SLB',
|
||||
taskType: 'deployCertToAliyunSLB',
|
||||
certStore: 'aliyun'
|
||||
},
|
||||
{
|
||||
name: '部署证书到阿里云集群Ingress',
|
||||
taskType: 'deployCertToAliyunK8sIngress',
|
||||
certStore: 'aliyun'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
deployName: '流程2-部署到nginx服务器',
|
||||
tasks: [
|
||||
{
|
||||
name: '上传证书到服务器,并重启nginx',
|
||||
taskType: 'sshAndExecute',
|
||||
ssh: 'myLinux',
|
||||
upload: [
|
||||
{ from: '{certPath}', to: '/xxx/xxx/xxx.cert.pem' },
|
||||
{ from: '{keyPath}', to: '/xxx/xxx/xxx.key' }
|
||||
],
|
||||
script: 'sudo systemctl restart nginx'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
deployName: '流程3-触发jenkins任务',
|
||||
tasks: [
|
||||
{
|
||||
name: '触发jenkins任务',
|
||||
taskType: 'sshAndExecute',
|
||||
ssh: 'myLinux',
|
||||
script: 'sudo systemctl restart nginx'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
_.merge(defaultOptions, optionsPrivate)
|
||||
|
||||
export default defaultOptions
|
|
@ -0,0 +1,17 @@
|
|||
import pkg from 'chai'
|
||||
import UploadCertToAliyun from '../../src/upload/upload-cert-to-aliyun/index.js'
|
||||
import options from '../options'
|
||||
import Certd from '@certd/certd'
|
||||
const { expect } = pkg
|
||||
describe('PluginUploadCertToAliyun', function () {
|
||||
it('#execute', function () {
|
||||
const plugin = new UploadCertToAliyun()
|
||||
const certd = new Certd()
|
||||
const cert = certd.readCurrentCert('xiaojunnuo@qq.com', ['*.docmirror.cn'])
|
||||
plugin.execute({
|
||||
providers: options.providers,
|
||||
cert,
|
||||
args: { name: '上传证书到阿里云', provider: 'aliyun' }
|
||||
})
|
||||
})
|
||||
})
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue