Commit e46d3e95 authored by 薛智杰's avatar 薛智杰

Merge branch 'kewei' into 'master'

Kewei



See merge request !2
parents fb65af1d e59246f5
...@@ -7,33 +7,29 @@ const result = require('../middleware/result') ...@@ -7,33 +7,29 @@ const result = require('../middleware/result')
const namespaceRoute = require('./namespace') const namespaceRoute = require('./namespace')
const serviceRoute = require('./service') const serviceRoute = require('./service')
// const rabbitmqRoute = require('./rabbitmq') const repositoryRouter = require('./repository')
// const zookeeperRoute = require('./zookeeper') const tag = require('./tag')
const commonServiceRoute = require('./commonService') const commonServiceRoute = require('./commonService')
const ingressRoute = require('./ingress') const ingressRoute = require('./ingress')
const client = require('../services/tke.service').create({ const cluster = require('../services/tke.clusterService').create()
secretId: 'AKID4rY7wwNphsUcaFsy1pRtKhQvDj4CA3Ac', const container = require('../services/tke.containerService').create()
secretKey: 'YBduRnjgVRGzmagZJbss3Vo58wWCyhgc',
clusterId: 'cls-acfx4pvj',
region: 'ap-beijing'
})
function loadRoutes (router) { function loadRoutes (router) {
router router
.use(error()) .use(error())
.use(result()) .use(result())
.use(async (ctx, next) => { .use(async (ctx, next) => {
// 腾讯云 // 腾讯云
ctx.client = client ctx.container = container
ctx.cluster = cluster
await next() await next()
}, bodyParser()) }, bodyParser())
.use('/namespace', namespaceRoute.routes()) .use('/namespace', namespaceRoute.routes())
.use('/service', serviceRoute.routes()) .use('/service', serviceRoute.routes())
// .use('/rabbitmq', rabbitmqRoute.routes()) .use('/commonService', commonServiceRoute.routes())
// .use('/zookeeper', zookeeperRoute.routes()) .use('/ingress', ingressRoute.routes())
.use('/commonService', commonServiceRoute.routes()) .use('/repository',repositoryRouter.routes())
.use('/ingress', ingressRoute.routes()) .use('/tag',tag.routes())
} }
exports.start = function () { exports.start = function () {
......
...@@ -4,17 +4,17 @@ const router = new Router(); ...@@ -4,17 +4,17 @@ const router = new Router();
module.exports = router module.exports = router
router.get('/', async ctx => { router.get('/', async ctx => {
let data = await ctx.client.namespace_get() let data = await ctx.cluster.namespace_get()
ctx.body = ctx.ok(data) ctx.body = ctx.ok(data)
}) })
router.post('/create', async ctx => { router.post('/create', async ctx => {
await ctx.client.namespace_create(ctx.request.body.name) await ctx.cluster.namespace_create(ctx.request.body.name)
await ctx.client.ingress_create(ctx.request.body.name) await ctx.cluster.ingress_create(ctx.request.body.name)
ctx.body = ctx.ok() ctx.body = ctx.ok()
}) })
router.post('/delete', async ctx => { router.post('/delete', async ctx => {
await ctx.client.namespace_delete(ctx.request.body.name) await ctx.cluster.namespace_delete(ctx.request.body.name)
ctx.body = ctx.ok() ctx.body = ctx.ok()
}) })
const Router = require('koa-router')
const yaml = require('js-yaml')
const templates = require('../serviceTemplate')
const IMAGES = ['rabbitmq:3.6-management']
const router = new Router()
module.exports = router
router.post('/create', async ctx => {
// let svc = await ctx.client.service_get('rabbitmq', ctx.request.body.namespace)
// if (svc) {
// ctx.body = ctx.fail('服务已经存在')
// return
// }
let data = {
namespace: ctx.request.body.namespace,
image: IMAGES[0]
}
let template = templates['rabbitmq'].replace(/{{([A-Za-z0-9_]+)}}/g, function () {
if (data[arguments[1]] === undefined) {
throw new Error('缺少模板所需变量')
}
return data[arguments[1]]
})
let params = yaml.load(template)
await ctx.client.service_create(params)
ctx.body = ctx.ok('创建成功')
})
router.post('/delete', async ctx => {
await ctx.client.service_delete('rabbitmq', ctx.request.body.namespace)
ctx.body = ctx.ok('删除成功')
})
const Router = require('koa-router')
const router = new Router()
module.exports = router
router.post('/', async ctx => {
let data = await ctx.container.repository_get(ctx.request.body.namespace)
ctx.body = ctx.ok(data)
})
...@@ -2,57 +2,52 @@ const Router = require('koa-router') ...@@ -2,57 +2,52 @@ const Router = require('koa-router')
const yaml = require('js-yaml') const yaml = require('js-yaml')
const templates = require('../serviceTemplate') const templates = require('../serviceTemplate')
const TYPES = ['ui', 'java', 'nodejs', 'python', 'go'] const TYPES = ['ui', 'java', 'node', 'python', 'go']
const router = new Router() const router = new Router()
module.exports = router module.exports = router
router.get('/', async ctx => { router.get('/', async ctx => {
let data = await ctx.client.service_list(ctx.query.namespace) let data = await ctx.cluster.service_list(ctx.query.namespace)
ctx.body = ctx.ok(data) ctx.body = ctx.ok(data)
}) })
router.post('/create', async ctx => { router.post('/create', async ctx => {
let { type, serviceName, namespace, image, system_name } = ctx.request.body let {type, serviceName, namespace, image, system_name, lable} = ctx.request.body
if (!TYPES.includes(type)) { if (!TYPES.includes(type)) {
return ctx.body = ctx.fail('不支持的服务类型') return ctx.body = ctx.fail('不支持的服务类型')
} }
let data = {
// try { serviceName,
// let svc = await ctx.client.service_get(serviceName, namespace) namespace,
// if (svc) { image,
// return ctx.body = ctx.fail('服务已经存在') system_name,
// } lable
// } catch (e) {
// }
let data = {
serviceName,
namespace,
image,
system_name
}
if (!system_name) {
// ui abTest的时候不一样
data.system_name = serviceName
}
let template = templates[type].replace(/{{([A-Za-z0-9_]+)}}/g, function () {
if (data[arguments[1]] === undefined) {
throw new Error('缺少模板所需变量')
} }
return data[arguments[1]] if (!system_name) {
}) // ui abTest的时候不一样
let params = yaml.load(template) data.system_name = serviceName
await ctx.client.service_create(params) }
ctx.body = ctx.ok('创建成功') let template = templates[type].replace(/{{([A-Za-z0-9_]+)}}/g, function () {
if (data[arguments[1]] === undefined) {
throw new Error('缺少模板所需变量')
}
return data[arguments[1]]
})
let params = yaml.load(template)
await ctx.cluster.service_create(params, type)
ctx.body = ctx.ok('创建成功')
})
router.post('/details', async ctx => {
let data = await ctx.cluster.service_get(ctx.request.body.serviceName, ctx.request.body.namespace)
ctx.body = ctx.ok(data)
}) })
router.post('/delete', async ctx => { router.post('/delete', async ctx => {
await ctx.client.service_delete(ctx.request.body.serviceName, ctx.request.body.namespace) await ctx.cluster.service_delete(ctx.request.body.serviceName, ctx.request.body.namespace)
ctx.body = ctx.ok('删除成功') ctx.body = ctx.ok('删除成功')
}) })
router.post('/modifyImage', async ctx => { router.post('/modifyImage', async ctx => {
await ctx.client.service_modifyImage(ctx.request.body.serviceName, ctx.request.body.image, ctx.request.body.namespace) await ctx.cluster.service_modifyImage(ctx.request.body.serviceName, ctx.request.body.image, ctx.request.body.namespace)
ctx.body = ctx.ok('更新成功') ctx.body = ctx.ok('更新成功')
}) })
const Router = require('koa-router')
const router = new Router()
module.exports = router
router.post('/', async ctx => {
let data = await ctx.container.tag_get(ctx.request.body.reponame)
ctx.body = ctx.ok(data)
})
const Router = require('koa-router')
const yaml = require('js-yaml')
const templates = require('../serviceTemplate')
const IMAGES = ['zookeeper:3.4.10']
const router = new Router()
module.exports = router
router.post('/create', async ctx => {
let data = {
namespace: ctx.request.body.namespace,
image: IMAGES[0]
}
let template = templates['zookeeper'].replace(/{{([A-Za-z0-9_]+)}}/g, function () {
if (data[arguments[1]] === undefined) {
throw new Error('缺少模板所需变量')
}
return data[arguments[1]]
})
let params = yaml.load(template)
await ctx.client.service_create(params)
ctx.body = ctx.ok('创建成功')
})
router.post('/delete', async ctx => {
await ctx.client.service_delete('zookeeper', ctx.request.body.namespace)
ctx.body = ctx.ok('删除成功')
})
module.exports={
secretId: 'AKID4rY7wwNphsUcaFsy1pRtKhQvDj4CA3Ac',
secretKey: 'YBduRnjgVRGzmagZJbss3Vo58wWCyhgc',
clusterId: 'cls-acfx4pvj',
region: 'ap-beijing',
method :'POST',
protocal : 'https://',
clusterPoint : 'ccs.api.qcloud.com', //访问集群以及服务的域名
containerPoint : 'ccr.api.qcloud.com', //访问镜像仓库的域名
path : '/v2/index.php',
domain : ".lkbang.com",
}
This diff is collapsed.
const fs = require('fs') const fs = require('fs')
const ui = fs.readFileSync('serviceTemplate/ui.template.txt', 'utf8') const ui = fs.readFileSync('serviceTemplate/ui.template.txt', 'utf8')
const java = fs.readFileSync('serviceTemplate/java.template.txt', 'utf8') const java = fs.readFileSync('serviceTemplate/java.template.txt', 'utf8')
const nodejs = fs.readFileSync('serviceTemplate/nodejs.template.txt', 'utf8') const node = fs.readFileSync('serviceTemplate/node.template.txt', 'utf8')
const rabbitmq = fs.readFileSync('serviceTemplate/rabbitmq.template.txt', 'utf8') const rabbitmq = fs.readFileSync('serviceTemplate/rabbitmq.template.txt', 'utf8')
const zookeeper = fs.readFileSync('serviceTemplate/zookeeper.template.txt', 'utf8') const zookeeper = fs.readFileSync('serviceTemplate/zookeeper.template.txt', 'utf8')
const mysql = fs.readFileSync('serviceTemplate/mysql.template.txt', 'utf8') const mysql = fs.readFileSync('serviceTemplate/mysql.template.txt', 'utf8')
module.exports = { module.exports = {
ui, ui,
nodejs, node,
java, java,
rabbitmq, rabbitmq,
zookeeper, zookeeper,
......
const Client = require('./tke.service')
const domainConfig = require('../config')
class Cluster extends Client {
constructor() {
super();
this.endpoint = domainConfig.clusterPoint
}
namespace_get() {
return this.post('DescribeClusterNameSpaces', {clusterId: this.clusterId})
}
namespace_create(name) {
return this.post('CreateClusterNamespace', {name, description: '', clusterId: this.clusterId})
}
namespace_delete(name) {
return this.post('DeleteClusterNamespace', {"names.0": name, clusterId: this.clusterId})
}
service_list(namespace) {
return this.post('DescribeClusterService', {namespace, clusterId: this.clusterId, allnamespace: 0})
}
service_get(serviceName, namespace) {
return this.post('DescribeClusterServiceInfo', {serviceName, namespace, clusterId: this.clusterId})
}
async service_create(params, type) {
params.clusterId = this.clusterId
let str = JSON.stringify(params)
await this.post('CreateClusterService', params)
let updateLabels = {
clusterId: params.clusterId,
serviceName: params.serviceName,
namespace: params.namespace,
"labels.type": type
}
return this.post('ModifyServiceLabels', updateLabels)
}
service_delete(serviceName, namespace) {
return this.post('DeleteClusterService', {serviceName, namespace, clusterId: this.clusterId})
}
service_modifyImage(serviceName, image, namespace) {
return this.post('ModifyClusterServiceImage', {serviceName, namespace, image, clusterId: this.clusterId})
}
ingress_get(namespace) {
return this.post('DescribeIngress', {namespace, clusterId: this.clusterId})
}
ingress_create(namespace) {
return this.post('CreateIngress', {
ingressName: `qa-${namespace}`,
ingressDesc: '',
namespace,
clusterId: this.clusterId
})
}
ingress_delete(ingressName, namespace) {
return this.post('DeleteIngress', {ingressName, namespace, clusterId: this.clusterId})
}
ingress_modify(ingressName, namespace, rules) {
return this.post('MosifyIngress', {ingressName, namespace, ...rules, clusterId: this.clusterId})
}
}
exports.create = function () {
return new Cluster()
}
const Client = require('./tke.service')
const domainConfig = require('../config')
class Container extends Client {
constructor() {
super();
this.endpoint = domainConfig.containerPoint
}
repository_get( namespace) {
return this.post('SearchUserRepository', {namespace})
}
tag_get( reponame) {
return this.post('GetTagList', {reponame})
}
}
exports.create = function () {
return new Container()
}
const request = require('request') const request = require('request')
const crypto = require('crypto') const crypto = require('crypto')
const domainConfig = require('../config')
class Client {
constructor ({secretId, secretKey, region, clusterId}) { class Client {
this.secretId = secretId constructor() {
this.secretKey = secretKey this.secretId = domainConfig.secretId
this.region = region this.secretKey = domainConfig.secretKey
this.clusterId = clusterId this.region = domainConfig.region
this.method = 'POST' this.clusterId = domainConfig.clusterId
this.protocal = 'https://' this.method = domainConfig.method
this.endpoint = 'ccs.api.qcloud.com' this.protocal = domainConfig.protocal
this.path = '/v2/index.php' this.endpoint = ''
this.domain = ".lkbang.com" this.path = domainConfig.path
this.domain = domainConfig.domain
// 禁止操作以下命名空间
this.defaultNamespaces = ['default', 'kube-system', 'kube-public'] // 禁止操作以下命名空间
} this.defaultNamespaces = ['default', 'kube-system', 'kube-public']
sign (params, signMethod) {
let str = ''
let keys = Object.keys(params)
keys.sort()
for (let key of keys) {
str += '&' + key + '=' + params[key]
} }
str = str.slice(1)
let signStr = this.method + this.endpoint + this.path + '?' + str
let signMethodMap = { sign(params, signMethod) {
HmacSHA1: "sha1", let str = ''
HmacSHA256: "sha256" let keys = Object.keys(params)
} keys.sort()
let hmac = crypto.createHmac(signMethodMap[signMethod], this.secretKey) for (let key of keys) {
return hmac.update(Buffer.from(signStr, 'utf-8')).digest('base64') str += '&' + key + '=' + params[key]
} }
str = str.slice(1)
let signStr = this.method + this.endpoint + this.path + '?' + str
// 公共参数 let signMethodMap = {
// Action: '', HmacSHA1: "sha1",
// Region: '', HmacSHA256: "sha256"
// Timestamp: null, }
// Nonce: null, let hmac = crypto.createHmac(signMethodMap[signMethod], this.secretKey)
// SecretId: '', return hmac.update(Buffer.from(signStr, 'utf-8')).digest('base64')
// Signature: '' }
formatRequestData (action, params = {}) {
params.Action = action
params.Region = this.region
params.Timestamp = Math.round(Date.now() / 1000)
params.Nonce = Math.round(Math.random() * 65535)
params.SecretId = this.secretId
params.SignatureMethod = params.SignatureMethod || 'HmacSHA256'
params.Signature = this.sign(params, params.SignatureMethod)
}
post (action, params = {}) { // 公共参数
if (params.namespace && this.defaultNamespaces.includes(params.namespace)) { // Action: '',
return Promise.reject(new Error('未授权的namespace')) // Region: '',
// Timestamp: null,
// Nonce: null,
// SecretId: '',
// Signature: ''
formatRequestData(action, params = {}) {
params.Action = action
params.Region = this.region
params.Timestamp = Math.round(Date.now() / 1000)
params.Nonce = Math.round(Math.random() * 65535)
params.SecretId = this.secretId
params.SignatureMethod = params.SignatureMethod || 'HmacSHA256'
params.Signature = this.sign(params, params.SignatureMethod)
} }
this.formatRequestData(action, params) post(action, params = {}) {
let url = this.protocal + this.endpoint + this.path if (params.namespace && this.defaultNamespaces.includes(params.namespace)) {
let self = this return Promise.reject(new Error('未授权的namespace'))
return new Promise(function (resolve, reject) {
request({
method: self.method,
url,
json: true,
form: params
}, function (err, res, body) {
if (err) {
console.error(err)
reject(err)
} else {
if (body.code === 0) {
resolve(body.data)
} else {
reject(body)
}
} }
})
})
}
namespace_get () {
return this.post('DescribeClusterNameSpaces', {clusterId: this.clusterId})
}
namespace_create (name) {
return this.post('CreateClusterNamespace', {name, description: '', clusterId: this.clusterId})
}
namespace_delete (name) {
return this.post('DeleteClusterNamespace', {"names.0": name, clusterId: this.clusterId})
}
service_list (namespace) {
return this.post('DescribeClusterService', {namespace, clusterId: this.clusterId, allnamespace: 0})
}
service_get (serviceName, namespace) {
return this.post('DescribeClusterServiceInfo', {serviceName, namespace, clusterId: this.clusterId})
}
async service_create (params) { this.formatRequestData(action, params)
params.clusterId = this.clusterId let url = this.protocal + this.endpoint + this.path
let str = JSON.stringify(params) let self = this
await this.post('CreateClusterService', params) return new Promise(function (resolve, reject) {
// 腾讯云api暂只能通过修改服务来改成Recreate策略 request({
let modifyParams = JSON.parse(str) method: self.method,
modifyParams.strategy = 'Recreate' url,
return this.post('ModifyClusterService', modifyParams) json: true,
} form: params
}, function (err, res, body) {
service_delete (serviceName, namespace) { if (err) {
return this.post('DeleteClusterService', {serviceName, namespace, clusterId: this.clusterId}) console.error(err)
} reject(err)
} else {
service_modifyImage (serviceName, image, namespace) { if (body.code === 0) {
// 修改示例的第一个容器 resolve(body.data)
return this.post('ModifyClusterServiceImage', {serviceName, namespace, image, clusterId: this.clusterId}) } else {
} reject(body)
}
ingress_get (namespace) { }
return this.post('DescribeIngress', {namespace, clusterId: this.clusterId}) })
} })
}
ingress_create (namespace) {
return this.post('CreateIngress', {ingressName: `qa-${namespace}`, ingressDesc: '', namespace, clusterId: this.clusterId})
}
ingress_delete (ingressName, namespace) {
return this.post('DeleteIngress', {ingressName, namespace, clusterId: this.clusterId})
}
ingress_modify (ingressName, namespace, rules) {
return this.post('MosifyIngress', {ingressName, namespace, ...rules, clusterId: this.clusterId})
}
}
exports.create = function (config) {
return new Client(config)
} }
// let client = new Client({ module.exports = Client
// secretId: 'AKID4rY7wwNphsUcaFsy1pRtKhQvDj4CA3Ac',
// secretKey: 'YBduRnjgVRGzmagZJbss3Vo58wWCyhgc',
// clusterId: 'cls-acfx4pvj',
// region: 'ap-beijing'
// })
// client.post('DescribeClusterNameSpaces', {clusterId: 'cls-acfx4pvj'}).then(res => {
// console.log(5, res)
// })
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment