├── .npmignore ├── .npmrc ├── example ├── .env.example └── serverless.yml ├── .eslintignore ├── .prettierignore ├── src ├── package.json ├── config.js ├── utils.js └── serverless.js ├── prettier.config.js ├── commitlint.config.js ├── .editorconfig ├── CONTRIBUTING.md ├── .gitignore ├── serverless.component.yml ├── jest.config.js ├── __tests__ ├── lib │ └── utils.js └── index.test.js ├── LICENSE ├── release.config.js ├── .github └── workflows │ ├── validate.yml │ ├── test.yml │ └── release.yml ├── docs └── configure.md ├── .eslintrc.js ├── package.json ├── CHANGELOG.md └── README.md /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | example -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /example/.env.example: -------------------------------------------------------------------------------- 1 | TENCENT_SECRET_ID=xxx 2 | TENCENT_SECRET_KEY=xxx -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | dist 3 | node_modules 4 | example 5 | *.test.js 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | coverage 2 | dist 3 | node_modules 4 | CHANGELOG.md 5 | *.test.js 6 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "tencent-component-toolkit": "^2.0.11", 4 | "type": "^2.1.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'always', 3 | printWidth: 100, 4 | semi: false, 5 | singleQuote: true, 6 | tabWidth: 2, 7 | trailingComma: 'none' 8 | } 9 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | const Configuration = { 2 | /* 3 | * Resolve and load @commitlint/config-conventional from node_modules. 4 | * Referenced packages must be installed 5 | */ 6 | extends: ['@commitlint/config-conventional'] 7 | } 8 | 9 | module.exports = Configuration 10 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | const CONFIGS = { 2 | region: 'ap-guangzhou', 3 | zone: 'ap-guangzhou-2', 4 | projectId: 0, 5 | dBVersion: '10.4', 6 | dBCharset: 'UTF8', 7 | extranetAccess: false, 8 | compName: 'PostgreSQL', 9 | compFullname: 'PostgreSQL' 10 | } 11 | 12 | module.exports = CONFIGS 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | end_of_line = lf 9 | insert_final_newline = true 10 | indent_size = 2 11 | indent_style = space 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /example/serverless.yml: -------------------------------------------------------------------------------- 1 | org: orgDemo 2 | app: appDemo 3 | stage: dev 4 | component: postgresql 5 | name: postgresqlDemo 6 | 7 | inputs: 8 | region: ap-guangzhou 9 | zone: ap-guangzhou-2 10 | dBInstanceName: postgresqlDemo 11 | vpcConfig: 12 | vpcId: vpc-b6531flb 13 | subnetId: subnet-eexos4wi 14 | extranetAccess: true 15 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a [code of conduct](./CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.sublime-project 3 | *.sublime-workspace 4 | *.log 5 | .serverless 6 | v8-compile-cache-* 7 | jest/* 8 | coverage 9 | .serverless_plugins 10 | testProjects/*/package-lock.json 11 | testProjects/*/yarn.lock 12 | .serverlessUnzipped 13 | node_modules 14 | .vscode/ 15 | .eslintcache 16 | dist 17 | .idea 18 | build/ 19 | .env* 20 | env.js 21 | package-lock.json 22 | test 23 | yarn.lock -------------------------------------------------------------------------------- /serverless.component.yml: -------------------------------------------------------------------------------- 1 | name: postgresql 2 | version: 0.1.4 3 | author: 'Tencent Cloud, Inc.' 4 | org: 'Tencent Cloud, Inc.' 5 | description: Postgre 组件, 允许用户创建部署一个 Serverless PostgreSQL 数据库实例。配合其他组件进行数据库相关应用开发。 6 | keywords: 'tencent, serverless, postgresql' 7 | repo: 'https://github.com/serverless-components/tencent-postgresql' 8 | readme: >- 9 | https://github.com/serverless-components/tencent-postgresql/tree/master/README.md 10 | license: MIT 11 | main: ./src 12 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const { join } = require('path') 2 | require('dotenv').config({ path: join(__dirname, '.env.test') }) 3 | 4 | const config = { 5 | verbose: true, 6 | silent: false, 7 | testTimeout: 600000, 8 | testEnvironment: 'node', 9 | testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(js|ts)$', 10 | testPathIgnorePatterns: ['/node_modules/', '/__tests__/lib/'], 11 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 12 | } 13 | 14 | module.exports = config 15 | -------------------------------------------------------------------------------- /__tests__/lib/utils.js: -------------------------------------------------------------------------------- 1 | const { ServerlessSDK } = require('@serverless/platform-client-china') 2 | 3 | /* 4 | * Generate random id 5 | */ 6 | const generateId = () => 7 | Math.random() 8 | .toString(36) 9 | .substring(6) 10 | 11 | /* 12 | * Initializes and returns an instance of the serverless sdk 13 | * @param ${string} orgName - the serverless org name. 14 | */ 15 | const getServerlessSdk = (orgName) => { 16 | const sdk = new ServerlessSDK({ 17 | context: { 18 | orgName 19 | } 20 | }) 21 | return sdk 22 | } 23 | 24 | module.exports = { generateId, getServerlessSdk } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Tencent Cloud, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /release.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | verifyConditions: [ 3 | '@semantic-release/changelog', 4 | '@semantic-release/git', 5 | '@semantic-release/github' 6 | ], 7 | plugins: [ 8 | [ 9 | '@semantic-release/commit-analyzer', 10 | { 11 | preset: 'angular', 12 | parserOpts: { 13 | noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'] 14 | } 15 | } 16 | ], 17 | [ 18 | '@semantic-release/release-notes-generator', 19 | { 20 | preset: 'angular', 21 | parserOpts: { 22 | noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'BREAKING'] 23 | }, 24 | writerOpts: { 25 | commitsSort: ['subject', 'scope'] 26 | } 27 | } 28 | ], 29 | [ 30 | '@semantic-release/changelog', 31 | { 32 | changelogFile: 'CHANGELOG.md' 33 | } 34 | ], 35 | [ 36 | '@semantic-release/git', 37 | { 38 | assets: ['package.json', 'src/**', 'CHANGELOG.md'], 39 | message: 'chore(release): version ${nextRelease.version} \n\n${nextRelease.notes}' 40 | } 41 | ], 42 | [ 43 | '@semantic-release/github', 44 | { 45 | assets: ['!.env'] 46 | } 47 | ] 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /.github/workflows/validate.yml: -------------------------------------------------------------------------------- 1 | name: Validate 2 | 3 | on: 4 | pull_request: 5 | branches: [master] 6 | 7 | jobs: 8 | lintAndFormatting: 9 | name: Lint & Formatting 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout repository 13 | uses: actions/checkout@v2 14 | with: 15 | # Ensure connection with 'master' branch 16 | fetch-depth: 2 17 | 18 | - name: Install Node.js and npm 19 | uses: actions/setup-node@v1 20 | with: 21 | node-version: 14.x 22 | registry-url: https://registry.npmjs.org 23 | 24 | - name: Retrieve dependencies from cache 25 | id: cacheNpm 26 | uses: actions/cache@v2 27 | with: 28 | path: | 29 | ~/.npm 30 | node_modules 31 | key: npm-v14-${{ runner.os }}-${{ github.ref }}-${{ hashFiles('package.json') }} 32 | restore-keys: | 33 | npm-v14-${{ runner.os }}-${{ github.ref }}- 34 | npm-v14-${{ runner.os }}-refs/heads/master- 35 | 36 | - name: Install dependencies 37 | if: steps.cacheNpm.outputs.cache-hit != 'true' 38 | run: | 39 | npm update --no-save 40 | npm update --save-dev --no-save 41 | 42 | - name: Validate Formatting 43 | run: npm run prettier:fix 44 | - name: Validate Lint rules 45 | run: npm run lint:fix 46 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | pull_request: 5 | branches: [master] 6 | 7 | jobs: 8 | test: 9 | name: Test 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout repository 13 | uses: actions/checkout@v2 14 | with: 15 | # Ensure connection with 'master' branch 16 | fetch-depth: 2 17 | 18 | - name: Install Node.js and npm 19 | uses: actions/setup-node@v1 20 | with: 21 | node-version: 14.x 22 | registry-url: https://registry.npmjs.org 23 | 24 | - name: Retrieve dependencies from cache 25 | id: cacheNpm 26 | uses: actions/cache@v2 27 | with: 28 | path: | 29 | ~/.npm 30 | node_modules 31 | key: npm-v14-${{ runner.os }}-${{ github.ref }}-${{ hashFiles('package.json') }} 32 | restore-keys: | 33 | npm-v14-${{ runner.os }}-${{ github.ref }}- 34 | npm-v14-${{ runner.os }}-refs/heads/master- 35 | 36 | - name: Install dependencies 37 | if: steps.cacheNpm.outputs.cache-hit != 'true' 38 | run: | 39 | npm update --no-save 40 | npm update --save-dev --no-save 41 | - name: Running tests 42 | run: npm run test 43 | env: 44 | TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }} 45 | TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }} 46 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | jobs: 8 | release: 9 | name: Release 10 | runs-on: ubuntu-latest 11 | env: 12 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v2 16 | with: 17 | persist-credentials: false 18 | 19 | - name: Install Node.js and npm 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: 14.x 23 | registry-url: https://registry.npmjs.org 24 | 25 | - name: Retrieve dependencies from cache 26 | id: cacheNpm 27 | uses: actions/cache@v2 28 | with: 29 | path: | 30 | ~/.npm 31 | node_modules 32 | key: npm-v14-${{ runner.os }}-refs/heads/master-${{ hashFiles('package.json') }} 33 | restore-keys: npm-v14-${{ runner.os }}-refs/heads/master- 34 | 35 | - name: Install dependencies 36 | if: steps.cacheNpm.outputs.cache-hit != 'true' 37 | run: | 38 | npm update --no-save 39 | npm update --save-dev --no-save 40 | - name: Releasing 41 | run: | 42 | npm run release 43 | env: 44 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 45 | GIT_AUTHOR_NAME: slsplus 46 | GIT_AUTHOR_EMAIL: slsplus.sz@gmail.com 47 | GIT_COMMITTER_NAME: slsplus 48 | GIT_COMMITTER_EMAIL: slsplus.sz@gmail.com 49 | -------------------------------------------------------------------------------- /docs/configure.md: -------------------------------------------------------------------------------- 1 | # 配置文档 2 | 3 | ## 完整配置 4 | 5 | ```yml 6 | # serverless.yml 7 | component: postgresql # (必填) 组件名称,此处为 postgresql 8 | name: serverlessDB # (必填) 实例名称 9 | org: test # (可选) 用于记录组织信息,默认值为您的腾讯云账户 appid 10 | app: serverlessDB # (可选) 该应用名称 11 | stage: dev # (可选) 用于区分环境信息,默认值为 dev 12 | 13 | inputs: 14 | region: ap-guangzhou # 可选 ap-guangzhou, ap-shanghai, ap-beijing 15 | zone: ap-guangzhou-2 # 可选 ap-guangzhou-2, ap-shanghai-2, ap-beijing-3 16 | dBInstanceName: serverlessDB 17 | projectId: 0 18 | dBVersion: 10.4 19 | dBCharset: UTF8 20 | vpcConfig: 21 | vpcId: vpc-123 22 | subnetId: subnet-123 23 | extranetAccess: false 24 | ``` 25 | 26 | ## 配置说明 27 | 28 | 主要参数说明 29 | 30 | | 参数 | 必填/可选 | 类型 | 默认值 | 描述 | 31 | | ------------------ | --------- | ------- | ------- | ---------------------------------- | 32 | | region | 必填 | String | | 数据库的所属地区 | 33 | | zone | 必填 | String | | 数据库所在地区的区域 | 34 | | dBInstanceName | 必填 | String | | 数据库实例名称,对一用户必须唯一 | 35 | | dBVersion | 可选 | string | `10.4` | PostgreSQL 版本号,目前支持: 10.4 | 36 | | dBCharset | 可选 | String | `UTF8` | 数据库的字符集编码 | 37 | | projectId | 可选 | Integer | `0` | 项目的 ID | 38 | | vpcConfig.vpcId | 必填 | String | | VPC 的 ID | 39 | | vpcConfig.subnetId | 可选 | String | | Subnet 的 ID | 40 | | extranetAccess | 可选 | Boolean | `false` | 是否开启 serverlessDB 实例外网访问 | 41 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | const ensureNumber = require('type/number/ensure') 2 | const ensureObject = require('type/object/ensure') 3 | const ensureString = require('type/string/ensure') 4 | const { ApiTypeError } = require('tencent-component-toolkit/lib/utils/error') 5 | const CONFIGS = require('./config') 6 | 7 | const prepareInputs = (inputs) => { 8 | try { 9 | inputs.dBInstanceName = ensureString(inputs.dBInstanceName, { 10 | errorMessage: 'dBInstanceName is required' 11 | }) 12 | inputs.region = ensureString(inputs.region, { default: CONFIGS.region }) 13 | inputs.zone = ensureString(inputs.zone, { default: CONFIGS.zone }) 14 | inputs.projectId = ensureNumber(inputs.projectId, { default: CONFIGS.projectId }) 15 | inputs.dBVersion = ensureString(inputs.dBVersion, { default: CONFIGS.dBVersion }) 16 | inputs.dBCharset = ensureString(inputs.dBCharset, { default: CONFIGS.dBCharset }) 17 | inputs.extranetAccess = inputs.extranetAccess === true ? true : CONFIGS.extranetAccess 18 | 19 | inputs.vpcConfig = ensureObject(inputs.vpcConfig, { 20 | isOptional: false, 21 | errorMessage: 'vpcConfig is required' 22 | }) 23 | inputs.vpcConfig.vpcId = ensureString(inputs.vpcConfig.vpcId, { 24 | isOptional: false, 25 | errorMessage: 'vpcId is required' 26 | }) 27 | inputs.vpcConfig.subnetId = ensureString(inputs.vpcConfig.subnetId, { 28 | isOptional: false, 29 | errorMessage: 'subnetId is required' 30 | }) 31 | } catch (e) { 32 | throw new ApiTypeError(`PARAMETER_${CONFIGS.compName.toUpperCase()}`, e.message, e.stack) 33 | } 34 | 35 | return inputs 36 | } 37 | 38 | module.exports = { 39 | prepareInputs 40 | } 41 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['prettier'], 4 | plugins: ['import', 'prettier'], 5 | env: { 6 | es6: true, 7 | jest: true, 8 | node: true 9 | }, 10 | parser: 'babel-eslint', 11 | parserOptions: { 12 | ecmaVersion: 2018, 13 | sourceType: 'module', 14 | ecmaFeatures: { 15 | jsx: true 16 | } 17 | }, 18 | globals: { 19 | on: true // for the Socket file 20 | }, 21 | rules: { 22 | 'array-bracket-spacing': [ 23 | 'error', 24 | 'never', 25 | { 26 | objectsInArrays: false, 27 | arraysInArrays: false 28 | } 29 | ], 30 | 'arrow-parens': ['error', 'always'], 31 | 'arrow-spacing': ['error', { before: true, after: true }], 32 | 'comma-dangle': ['error', 'never'], 33 | curly: 'error', 34 | 'eol-last': 'error', 35 | 'func-names': 'off', 36 | 'id-length': [ 37 | 'error', 38 | { 39 | min: 1, 40 | max: 50, 41 | properties: 'never', 42 | exceptions: ['e', 'i', 'n', 't', 'x', 'y', 'z', '_', '$'] 43 | } 44 | ], 45 | 'no-alert': 'error', 46 | 'no-console': 'off', 47 | 'no-const-assign': 'error', 48 | 'no-else-return': 'error', 49 | 'no-empty': 'off', 50 | 'no-shadow': 'error', 51 | 'no-undef': 'error', 52 | 'no-unused-vars': 'error', 53 | 'no-use-before-define': 'error', 54 | 'no-useless-constructor': 'error', 55 | 'object-curly-newline': 'off', 56 | 'object-shorthand': 'off', 57 | 'prefer-const': 'error', 58 | 'prefer-destructuring': ['error', { object: true, array: false }], 59 | quotes: [ 60 | 'error', 61 | 'single', 62 | { 63 | allowTemplateLiterals: true, 64 | avoidEscape: true 65 | } 66 | ], 67 | semi: ['error', 'never'], 68 | 'spaced-comment': 'error', 69 | strict: ['error', 'global'], 70 | 'prettier/prettier': 'error' 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@serverless/postgresql", 3 | "main": "src/serverless.js", 4 | "publishConfig": { 5 | "access": "public" 6 | }, 7 | "scripts": { 8 | "test": "jest", 9 | "commitlint": "commitlint -f HEAD@{15}", 10 | "lint": "eslint --ext .js,.ts,.tsx .", 11 | "lint:fix": "eslint --fix --ext .js,.ts,.tsx .", 12 | "prettier": "prettier --check '**/*.{css,html,js,json,md,yaml,yml}'", 13 | "prettier:fix": "prettier --write '**/*.{css,html,js,json,md,yaml,yml}'", 14 | "release": "semantic-release", 15 | "release-local": "node -r dotenv/config node_modules/semantic-release/bin/semantic-release --no-ci --dry-run", 16 | "check-dependencies": "npx npm-check --skip-unused --update" 17 | }, 18 | "husky": { 19 | "hooks": { 20 | "pre-commit": "ygsec && lint-staged", 21 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", 22 | "pre-push": "ygsec && npm run lint:fix && npm run prettier:fix" 23 | } 24 | }, 25 | "lint-staged": { 26 | "**/*.{js,ts,tsx}": [ 27 | "npm run lint:fix", 28 | "git add ." 29 | ], 30 | "**/*.{css,html,js,json,md,yaml,yml}": [ 31 | "npm run prettier:fix", 32 | "git add ." 33 | ] 34 | }, 35 | "author": "Tencent Cloud, Inc.", 36 | "license": "MIT", 37 | "dependencies": {}, 38 | "devDependencies": { 39 | "@commitlint/cli": "^8.3.5", 40 | "@commitlint/config-conventional": "^8.3.4", 41 | "@semantic-release/changelog": "^5.0.0", 42 | "@semantic-release/commit-analyzer": "^8.0.1", 43 | "@semantic-release/git": "^9.0.0", 44 | "@semantic-release/npm": "^7.0.4", 45 | "@semantic-release/release-notes-generator": "^9.0.1", 46 | "@serverless/platform-client-china": "^2.1.4", 47 | "@ygkit/secure": "0.0.3", 48 | "babel-eslint": "^10.1.0", 49 | "dotenv": "^8.2.0", 50 | "eslint": "^6.8.0", 51 | "eslint-config-prettier": "^6.10.0", 52 | "eslint-plugin-import": "^2.20.1", 53 | "eslint-plugin-prettier": "^3.1.2", 54 | "husky": "^4.2.5", 55 | "jest": "^26.6.3", 56 | "lint-staged": "^10.0.8", 57 | "prettier": "^1.19.1", 58 | "semantic-release": "^17.0.4" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/serverless.js: -------------------------------------------------------------------------------- 1 | const { Component } = require('@serverless/core') 2 | const { Postgresql } = require('tencent-component-toolkit') 3 | const { ApiTypeError } = require('tencent-component-toolkit/lib/utils/error') 4 | const { prepareInputs } = require('./utils') 5 | 6 | class ServerlessComponent extends Component { 7 | getCredentials() { 8 | const { tmpSecrets } = this.credentials.tencent 9 | 10 | if (!tmpSecrets || !tmpSecrets.TmpSecretId) { 11 | throw new ApiTypeError( 12 | 'CREDENTIAL', 13 | 'Cannot get secretId/Key, your account could be sub-account and does not have the access to use SLS_QcsRole, please make sure the role exists first, then visit https://cloud.tencent.com/document/product/1154/43006, follow the instructions to bind the role to your account.' 14 | ) 15 | } 16 | 17 | return { 18 | SecretId: tmpSecrets.TmpSecretId, 19 | SecretKey: tmpSecrets.TmpSecretKey, 20 | Token: tmpSecrets.Token 21 | } 22 | } 23 | 24 | async deploy(inputs) { 25 | console.log(`Deploying PostgreSQL Database...`) 26 | 27 | const credentials = this.getCredentials() 28 | 29 | // 对Inputs内容进行标准化 30 | const pgInputs = await prepareInputs(inputs) 31 | if (this.state.dBInstanceId) { 32 | pgInputs.dBInstanceId = this.state.dBInstanceId 33 | } 34 | const pgBaas = new Postgresql(credentials, pgInputs.region) 35 | // 部署函数 + API网关 36 | const outputs = await pgBaas.deploy(pgInputs) 37 | 38 | // optimize outputs for one region 39 | this.state.region = pgInputs.region 40 | this.state.zone = pgInputs.zone 41 | this.state.dBInstanceId = outputs.dBInstanceId 42 | this.state.dBInstanceName = outputs.dBInstanceName 43 | 44 | return outputs 45 | } 46 | 47 | async remove() { 48 | console.log(`Removing PostgreSQL Database...`) 49 | 50 | const { state } = this 51 | 52 | const credentials = this.getCredentials() 53 | 54 | const pgBaas = new Postgresql(credentials, state.region) 55 | 56 | await pgBaas.remove({ 57 | dBInstanceId: state.dBInstanceId, 58 | dBInstanceName: state.dBInstanceName 59 | }) 60 | 61 | this.state = {} 62 | } 63 | } 64 | 65 | module.exports = ServerlessComponent 66 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.1.1](https://github.com/serverless-components/tencent-postgresql/compare/v0.1.0...v0.1.1) (2021-02-15) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * db instance id not exist for getting detail ([1d8f680](https://github.com/serverless-components/tencent-postgresql/commit/1d8f680309ee7769458b02905139d39b9d519738)) 7 | 8 | # [0.1.0](https://github.com/serverless-components/tencent-postgresql/compare/v0.0.9...v0.1.0) (2021-02-03) 9 | 10 | 11 | ### Features 12 | 13 | * refactor deploy and remove using db instance id ([95c8f3e](https://github.com/serverless-components/tencent-postgresql/commit/95c8f3ef71316e00027feeb0b9f288870bab6934)) 14 | 15 | ## [0.0.9](https://github.com/serverless-components/tencent-postgresql/compare/v0.0.8...v0.0.9) (2020-09-07) 16 | 17 | 18 | ### Bug Fixes 19 | 20 | * update deps ([82670c8](https://github.com/serverless-components/tencent-postgresql/commit/82670c8a3a4faeca823a1dfaabf2f2e8c677de6f)) 21 | 22 | ## [0.0.8](https://github.com/serverless-components/tencent-postgresql/compare/v0.0.7...v0.0.8) (2020-09-03) 23 | 24 | 25 | ### Bug Fixes 26 | 27 | * update deps ([5553691](https://github.com/serverless-components/tencent-postgresql/commit/5553691d89f5e404d47ccbec5b9729681be3ce97)) 28 | 29 | ## [0.0.7](https://github.com/serverless-components/tencent-postgresql/compare/v0.0.6...v0.0.7) (2020-08-28) 30 | 31 | 32 | ### Bug Fixes 33 | 34 | * get credentials from temp secrets ([e3b16b5](https://github.com/serverless-components/tencent-postgresql/commit/e3b16b5dd3953b8ada5fc8dfa99b0b6a42d24404)) 35 | * throw error when no temp secrets ([4127111](https://github.com/serverless-components/tencent-postgresql/commit/4127111bf8839766d3d1f57d17434a473a3a5caf)) 36 | * update deps ([a536640](https://github.com/serverless-components/tencent-postgresql/commit/a536640b8408f56c9796780dffb193459a1bb5eb)) 37 | * update error message ([5222eb9](https://github.com/serverless-components/tencent-postgresql/commit/5222eb9b90c737f48f27a98dbfc74af4e1debda8)) 38 | * update toolkit verison ([acbd64f](https://github.com/serverless-components/tencent-postgresql/commit/acbd64f16f3cb23c3f56b5dbda78b3bcea60a747)) 39 | * upgrade tencent-component-toolkit for pg exist judgement ([9b605bf](https://github.com/serverless-components/tencent-postgresql/commit/9b605bf8b7c7a6624b24bb4e1610fb6aa7c2002f)) 40 | 41 | 42 | ### Features 43 | 44 | * init project ([97e9290](https://github.com/serverless-components/tencent-postgresql/commit/97e92908025b955fab0068b238a46071ea51ef16)) 45 | * release v0.0.6 ([1a1ddbc](https://github.com/serverless-components/tencent-postgresql/commit/1a1ddbcf058db11c7286236fc3dd2f16fa90ea81)) 46 | * support type error ([4793224](https://github.com/serverless-components/tencent-postgresql/commit/4793224fd43fcced5c0a3a087a3de9f27e242836)) 47 | -------------------------------------------------------------------------------- /__tests__/index.test.js: -------------------------------------------------------------------------------- 1 | const { generateId, getServerlessSdk } = require('./lib/utils') 2 | 3 | const instanceYaml = { 4 | org: 'orgDemo', 5 | app: 'appDemo', 6 | component: 'postgresql@dev', 7 | name: `postgresql-integration-tests-${generateId()}`, 8 | stage: 'dev', 9 | inputs: { 10 | region: 'ap-guangzhou', 11 | zone: 'ap-guangzhou-2', 12 | dBInstanceName: "serverless-test", 13 | vpcConfig: { 14 | vpcId: 'vpc-b6531flb', 15 | subnetId: 'subnet-eexos4wi', 16 | }, 17 | } 18 | } 19 | 20 | const credentials = { 21 | tencent: { 22 | SecretId: process.env.TENCENT_SECRET_ID, 23 | SecretKey: process.env.TENCENT_SECRET_KEY, 24 | } 25 | } 26 | 27 | const sdk = getServerlessSdk(instanceYaml.org) 28 | 29 | describe('Postgresql', () => { 30 | it('deploy postgresql success', async () => { 31 | const instance = await sdk.deploy(instanceYaml, credentials) 32 | expect(instance).toBeDefined() 33 | expect(instance.instanceName).toEqual(instanceYaml.name) 34 | expect(instance.outputs).toEqual({ 35 | region: instanceYaml.inputs.region, 36 | zone: instanceYaml.inputs.zone, 37 | vpcConfig: instanceYaml.inputs.vpcConfig, 38 | dBInstanceName: instanceYaml.inputs.dBInstanceName, 39 | dBInstanceId: expect.stringContaining('postgres-'), 40 | private: { 41 | connectionString: expect.stringContaining('postgresql://'), 42 | host: expect.any(String), 43 | port: 5432, 44 | user: expect.stringContaining('tencentdb_'), 45 | password: expect.any(String), 46 | dbname: expect.stringContaining('tencentdb_'), 47 | }, 48 | vendorMessage: null, 49 | }); 50 | }) 51 | 52 | it('update postgresql success', async () => { 53 | instanceYaml.inputs.extranetAccess = true 54 | const instance = await sdk.deploy(instanceYaml, credentials) 55 | expect(instance).toBeDefined() 56 | expect(instance.instanceName).toEqual(instanceYaml.name) 57 | expect(instance.outputs).toEqual({ 58 | region: instanceYaml.inputs.region, 59 | zone: instanceYaml.inputs.zone, 60 | vpcConfig: instanceYaml.inputs.vpcConfig, 61 | dBInstanceName: instanceYaml.inputs.dBInstanceName, 62 | dBInstanceId: expect.stringContaining('postgres-'), 63 | private: { 64 | connectionString: expect.stringContaining('postgresql://'), 65 | host: expect.any(String), 66 | port: 5432, 67 | user: expect.stringContaining('tencentdb_'), 68 | password: expect.any(String), 69 | dbname: expect.stringContaining('tencentdb_'), 70 | }, 71 | public: { 72 | connectionString: expect.stringContaining('postgresql://'), 73 | host: expect.any(String), 74 | port: expect.any(Number), 75 | user: expect.stringContaining('tencentdb_'), 76 | password: expect.any(String), 77 | dbname: expect.stringContaining('tencentdb_'), 78 | }, 79 | vendorMessage: null, 80 | }); 81 | }) 82 | 83 | it('remove postgresql success', async () => { 84 | await sdk.remove(instanceYaml, credentials) 85 | result = await sdk.getInstance(instanceYaml.org, instanceYaml.stage, instanceYaml.app, instanceYaml.name) 86 | 87 | expect(result.instance.instanceStatus).toEqual('inactive') 88 | }) 89 | }) 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 腾讯云 PostgreSQL DB 组件 2 | 3 | ## 简介 4 | 5 | 腾讯云 PostgreSQL DB 组件通过使用 [Serverless Framework](https://github.com/serverless/components),基于云上 Serverless 服务,实现“0”配置,便捷开发,可以快速方便的创建,部署和管理腾讯云的 PostgreSQL 产品。 6 | 7 | 特性介绍: 8 | 9 | - [x] **按需付费** - 按照请求的使用量进行收费,没有请求时无需付费。 10 | - [x] **"0"配置** - 默认配置将由 Serverless 完成。 11 | - [x] **极速部署** - 仅需几秒,创建或更新您的数据库。 12 | - [x] **便捷协作** - 通过云端数据库的状态信息和部署日志,方便的进行多人协作开发。 13 | 14 |
15 | 16 | ## 快速开始 17 | 18 | 1. [安装](#1-安装) 19 | 2. [创建](#2-创建) 20 | 3. [配置](#3-配置) 21 | 4. [账号配置](#4-账号配置) 22 | 5. [部署](#5-部署) 23 | 6. [查看状态](#6-查看状态) 24 | 7. [移除](#7-移除) 25 | 26 | ### 1. 安装 27 | 28 | 通过 npm 全局安装 最新版本的 Serverless Framework 29 | 30 | ```shell 31 | $ npm install -g serverless 32 | ``` 33 | 34 | ### 2. 创建 35 | 36 | 创建并进入一个全新目录: 37 | 38 | ``` 39 | $ mkdir tencent-postgresql && cd tencent-postgresql 40 | ``` 41 | 42 | ### 3. 配置 43 | 44 | 在新目录下创建 `serverless.yml` 文件,在其中进行如下配置 45 | 46 | ```shell 47 | $ touch serverless.yml 48 | ``` 49 | 50 | ```yml 51 | # serverless.yml 52 | component: postgresql #(必填) 引用 component 的名称,当前用到的是 postgresql 组件 53 | name: serverlessDB # (必填) 该 postgresql 组件创建的实例名称 54 | org: test # (可选) 用于记录组织信息,默认值为您的腾讯云账户 appid 55 | app: serverlessDB # (可选) 该 sql 应用名称 56 | stage: dev # (可选) 用于区分环境信息,默认值是 dev 57 | 58 | inputs: 59 | region: ap-guangzhou # 可选 ap-guangzhou, ap-shanghai, ap-beijing 60 | zone: ap-guangzhou-2 # 可选 ap-guangzhou-2, ap-shanghai-2, ap-beijing-3 61 | dBInstanceName: serverlessDB 62 | vpcConfig: 63 | vpcId: vpc-id3zoj6r 64 | subnetId: subnet-kwc49rti 65 | extranetAccess: false 66 | ``` 67 | 68 | PostgreSQL 组件支持 0 配置部署,也就是可以直接通过配置文件中的默认值进行部署。但你依然可以修改更多可选配置来进一步开发该项目。 69 | 70 | - [更多配置](https://github.com/serverless-tencent/tencent-postgresql/tree/master/docs/configure.md) 71 | 72 | > 注:当前 PGSQL for Serverless 仅支持 `北京三区,广州二区,上海二区` 三个地域的创建和部署,因此在填写 yaml 中的地域可用区时需要注意填写为正确的地域和对应的 VPC 子网信息。 73 | 74 | ### 4. 账号配置 75 | 76 | PostgreSQL 组件当前暂不支持 CLI 扫描二维码登录,因此您需要本地创建 `.env` 文件来配置持久的环境变量/秘钥信息, 77 | 78 | ```bash 79 | $ touch .env # 腾讯云的配置信息 80 | ``` 81 | 82 | 在 `.env` 文件中配置腾讯云的 SecretId 和 SecretKey 信息并保存 83 | 84 | 如果没有腾讯云账号,可以在此 [注册新账号](https://cloud.tencent.com/register)。 85 | 86 | 如果已有腾讯云账号,可以在 [API 密钥管理](https://console.cloud.tencent.com/cam/capi) 中获取 `SecretId` 和`SecretKey`. 87 | 88 | ```text 89 | # .env 90 | TENCENT_SECRET_ID=123 91 | TENCENT_SECRET_KEY=123 92 | ``` 93 | 94 | ### 5. 部署 95 | 96 | 通过 `sls` 命令进行部署,并可以添加 `--debug` 参数查看部署过程中的信息 97 | 98 | ```bash 99 | $ sls deploy 100 | ``` 101 | 102 | > 注意: `sls` 是 `serverless` 命令的简写。 103 | > 如您的账号未 [登录](https://cloud.tencent.com/login) 或 [注册](https://cloud.tencent.com/register) 腾讯云,您需要在本地创建.env 文件储存账户信息,详情请看[账号配置](#4-账号配置)。 104 | 105 | ### 6. 查看状态 106 | 107 | 在`serverless.yml`文件所在的目录下,通过如下命令查看部署状态: 108 | 109 | ``` 110 | $ sls info 111 | ``` 112 | 113 | ### 7. 移除 114 | 115 | 通过以下命令移除部署的 DB 实例,移除后该组件会对应删除云上部署时所创建的所有相关资源。 116 | 117 | ```bash 118 | $ sls remove 119 | ``` 120 | 121 | 和部署类似,支持通过 `sls remove --debug` 命令查看移除过程中的实时日志信息,`sls`是 `serverless` 命令的缩写。 122 | 123 | ### 更多组件 124 | 125 | 可以在 [Serverless Components](https://github.com/serverless/components) repo 中查询更多组件的信息。 126 | 127 | ## License 128 | 129 | MIT License 130 | 131 | Copyright (c) 2020 Tencent Cloud, Inc. 132 | --------------------------------------------------------------------------------