From d0187d0aad431504515d724f0d75a0e731c2bddc Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E5=88=98=E6=B4=AA=E9=9D=92?= Date: Wed, 19 Aug 2020 14:55:05 +0800 Subject: [PATCH] =?utf8?q?chore:=20=E6=96=B0=E5=A2=9E=E6=96=B0=E5=BC=80?= =?utf8?q?=E6=99=AE=E9=83=91=E5=B7=9E=E6=B5=8B=E8=AF=95=E7=8E=AF=E5=A2=83?= =?utf8?q?=E7=9A=84=E9=83=A8=E7=BD=B2=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- ...50\347\275\262\346\236\266\346\236\204.md" | 4 + ...50\347\275\262\346\211\213\345\206\214.md" | 599 ++++++++++++++++++ ...0\347\275\262\346\211\213\345\206\214.pdf" | Bin 0 -> 146441 bytes ...15\345\212\241\346\263\250\345\206\214.md" | 7 + ...71\346\216\245\350\257\264\346\230\216.md" | 14 + .../0.infras/0.0.0.infras-base.yaml | 17 + .../0.infras/0.0.1.infras-mysql.yaml | 102 +++ .../0.infras/0.0.2.infras-sba.yaml | 117 ++++ .../0.infras/0.0.x.infras-monitor.yaml | 21 + .../0.trans-service-v4-base.yaml | 47 ++ .../1.trans-service-v4-env.yaml | 26 + .../4.0.trans-service-v4-installer.yaml | 46 ++ .../5.trans-service-v4-datax-job.yaml | 55 ++ .../0.authx-service/0.authx-service-base.yaml | 16 + .../1.authx-service-mysql.yaml | 32 + .../2.authx-service-minio.yaml | 115 ++++ .../0.authx-service/8.echo-server.yaml | 58 ++ .../9.poa-api-docs-installer.yaml | 47 ++ .../0.thirdparty-agent-service-base.yaml | 16 + .../1.thirdparty-agent-service-env.yaml | 26 + .../4.2.thirdparty-agent-service.yaml | 149 +++++ .../k8s-rancher/1.authx-service/10.0.init.sql | 102 +++ .../k8s-rancher/1.authx-service/10.0.tmp.sql | 206 ++++++ .../1.authx-service/10.0.trans.sql | 73 +++ .../1.authx-service/10.1.init-flow.sql | 122 ++++ .../1.authx-service/10.1.init-message.sql | 78 +++ .../1.authx-service/10.1.init-portal.sql | 140 ++++ .../0.user-data-service-base.yaml | 213 +++++++ .../1.user-data-service-env.yaml | 52 ++ .../2.user-data-service-ingresses.yaml | 20 + .../4.0.user-data-service-installer.yaml | 46 ++ .../4.1.user-data-service-poa.yaml | 117 ++++ .../4.2.user-data-service-goa.yaml | 137 ++++ .../4.3.user-data-service-biz.yaml | 112 ++++ .../5.user-data-service-datax-job.yaml | 56 ++ .../0.user-authorization-service-base.yaml | 17 + .../1.user-authorization-service-env.yaml | 26 + ....user-authorization-service-ingresses.yaml | 27 + .../4.0.user-authorization-installer.yaml | 47 ++ .../4.1.user-authorization-poa.yaml | 110 ++++ .../4.2.user-authorization-sa.yaml | 106 ++++ .../5.user-authorization-datax-job.yaml | 57 ++ .../4.cas-server/0.cas-server-base.yaml | 215 +++++++ .../4.cas-server/1.cas-server-env.yaml | 51 ++ .../4.cas-server/2.cas-server-ingresses.yaml | 41 ++ .../4.0.cas-server-installer.yaml | 47 ++ .../4.cas-server/4.2.cas-server-sa-api.yaml | 125 ++++ .../4.3.cas-server-security-engine.yaml | 88 +++ .../4.5.cas-server-site-webapp.yaml | 235 +++++++ .../4.cas-server/5.cas-server-datax-job.yaml | 57 ++ .../certs/jwt/jwt_private_key.pem | 27 + .../certs/jwt/jwt_private_key_pkcs8.pem | 28 + .../4.cas-server/certs/jwt/jwt_public_key.pem | 9 + .../4.cas-server/certs/jwt/readme.md | 98 +++ .../5.token-server/0.token-server-base.yaml | 143 +++++ .../5.token-server/1.token-server-env.yaml | 38 ++ .../2.token-server-ingresses.yaml | 23 + .../4.0.token-server-installer.yaml | 47 ++ .../5.token-server/4.1.token-server.yaml | 176 +++++ .../0.personal-security-center-base.yaml | 144 +++++ .../1.personal-security-center-env.yaml | 22 + .../2.personal-security-center-ingresses.yaml | 41 ++ .../4.4.personal-security-center-bff.yaml | 225 +++++++ .../4.5.personal-security-center-zuul.yaml | 169 +++++ .../4.9.security-center-ui.yaml | 70 ++ .../certs/jwt/readme.md | 83 +++ .../0.communicate-center-base.yaml | 17 + .../1.communicate-center-env.yaml | 27 + .../2.communicate-center-ingresses.yaml | 19 + .../4.0.communicate-center-installer.yaml | 46 ++ .../4.1.communicate-center-poa.yaml | 111 ++++ .../9.jobs-server/0.jobs-server-base.yaml | 88 +++ .../9.jobs-server/1.jobs-server-env.yaml | 23 + .../9.jobs-server/4.1.jobs-server.yaml | 191 ++++++ .../6.admin-platform/10.0.init.sql | 73 +++ .../6.admin-platform/10.1.init-flow.sql | 96 +++ .../6.admin-platform/10.1.init-message.sql | 105 +++ .../6.admin-platform/10.1.init-portal.sql | 287 +++++++++ .../6.admin-center/0.admin-center-base.yaml | 188 ++++++ .../6.admin-center/1.admin-center-env.yaml | 39 ++ .../2.admin-center-ingresses.yaml | 62 ++ .../4.0.admin-center-sa-installer.yaml | 47 ++ .../6.admin-center/4.1.admin-center-poa.yaml | 117 ++++ .../6.admin-center/4.2.admin-center-sa.yaml | 101 +++ .../6.admin-center/4.4.admin-center-bff.yaml | 143 +++++ .../6.admin-center/4.5.admin-center-zuul.yaml | 170 +++++ .../4.9.admin-center-management.yaml | 69 ++ .../6.admin-center/certs/jwt/readme.md | 83 +++ .../0.admin-platform-base.yaml | 29 + .../2.admin-platform-ingresses.yaml | 36 ++ .../7.admin-platform/4.2.admin-platform.yaml | 74 +++ 91 files changed, 7821 insertions(+) create mode 100644 "project/newcapec-test/k8s-rancher/0.1.0.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\351\203\250\347\275\262\346\236\266\346\236\204.md" create mode 100644 "project/newcapec-test/k8s-rancher/0.1.1.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\345\256\211\350\243\205\351\203\250\347\275\262\346\211\213\345\206\214.md" create mode 100644 "project/newcapec-test/k8s-rancher/0.1.1.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\345\256\211\350\243\205\351\203\250\347\275\262\346\211\213\345\206\214.pdf" create mode 100644 "project/newcapec-test/k8s-rancher/0.2.1.POA\357\274\210\345\271\263\345\217\260OpenAPI\357\274\211\346\234\215\345\212\241\346\263\250\345\206\214.md" create mode 100644 "project/newcapec-test/k8s-rancher/0.2.2.\347\237\255\344\277\241\345\271\263\345\217\260\345\257\271\346\216\245\350\257\264\346\230\216.md" create mode 100644 project/newcapec-test/k8s-rancher/0.infras/0.0.0.infras-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/0.infras/0.0.1.infras-mysql.yaml create mode 100644 project/newcapec-test/k8s-rancher/0.infras/0.0.2.infras-sba.yaml create mode 100644 project/newcapec-test/k8s-rancher/0.infras/0.0.x.infras-monitor.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/0.trans-service-v4-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/1.trans-service-v4-env.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/4.0.trans-service-v4-installer.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/5.trans-service-v4-datax-job.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/0.authx-service-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/1.authx-service-mysql.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/2.authx-service-minio.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/8.echo-server.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/9.poa-api-docs-installer.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/0.thirdparty-agent-service-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/1.thirdparty-agent-service-env.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/4.2.thirdparty-agent-service.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/10.0.init.sql create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/10.0.tmp.sql create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/10.0.trans.sql create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-flow.sql create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-message.sql create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-portal.sql create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/0.user-data-service-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/1.user-data-service-env.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/2.user-data-service-ingresses.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.0.user-data-service-installer.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.1.user-data-service-poa.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.2.user-data-service-goa.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.3.user-data-service-biz.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/5.user-data-service-datax-job.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/0.user-authorization-service-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/1.user-authorization-service-env.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/2.user-authorization-service-ingresses.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.0.user-authorization-installer.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.1.user-authorization-poa.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.2.user-authorization-sa.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/5.user-authorization-datax-job.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/0.cas-server-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/1.cas-server-env.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/2.cas-server-ingresses.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.0.cas-server-installer.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.2.cas-server-sa-api.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.3.cas-server-security-engine.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.5.cas-server-site-webapp.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/5.cas-server-datax-job.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_private_key.pem create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_private_key_pkcs8.pem create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_public_key.pem create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/readme.md create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/0.token-server-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/1.token-server-env.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/2.token-server-ingresses.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/4.0.token-server-installer.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/4.1.token-server.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/0.personal-security-center-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/1.personal-security-center-env.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/2.personal-security-center-ingresses.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.4.personal-security-center-bff.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.5.personal-security-center-zuul.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.9.security-center-ui.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/certs/jwt/readme.md create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/0.communicate-center-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/1.communicate-center-env.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/2.communicate-center-ingresses.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/4.0.communicate-center-installer.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/4.1.communicate-center-poa.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/0.jobs-server-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/1.jobs-server-env.yaml create mode 100644 project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/4.1.jobs-server.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/10.0.init.sql create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-flow.sql create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-message.sql create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-portal.sql create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/0.admin-center-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/1.admin-center-env.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/2.admin-center-ingresses.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.0.admin-center-sa-installer.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.1.admin-center-poa.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.2.admin-center-sa.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.4.admin-center-bff.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.5.admin-center-zuul.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.9.admin-center-management.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/certs/jwt/readme.md create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/0.admin-platform-base.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/2.admin-platform-ingresses.yaml create mode 100644 project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/4.2.admin-platform.yaml diff --git "a/project/newcapec-test/k8s-rancher/0.1.0.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\351\203\250\347\275\262\346\236\266\346\236\204.md" "b/project/newcapec-test/k8s-rancher/0.1.0.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\351\203\250\347\275\262\346\236\266\346\236\204.md" new file mode 100644 index 0000000..27ca2d8 --- /dev/null +++ "b/project/newcapec-test/k8s-rancher/0.1.0.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\351\203\250\347\275\262\346\236\266\346\236\204.md" @@ -0,0 +1,4 @@ + +# 认证授权服务部署架构 + + diff --git "a/project/newcapec-test/k8s-rancher/0.1.1.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\345\256\211\350\243\205\351\203\250\347\275\262\346\211\213\345\206\214.md" "b/project/newcapec-test/k8s-rancher/0.1.1.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\345\256\211\350\243\205\351\203\250\347\275\262\346\211\213\345\206\214.md" new file mode 100644 index 0000000..89e4873 --- /dev/null +++ "b/project/newcapec-test/k8s-rancher/0.1.1.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\345\256\211\350\243\205\351\203\250\347\275\262\346\211\213\345\206\214.md" @@ -0,0 +1,599 @@ + +# 安装部署手册 + +**业务中台之认证授权服务** + + +* 修订历史 + +版本 | 作者 | 日期 | 备注 +- | - | - | - +v1 | 刘洪青 | 2020-06-10 | 初稿 + + +[TOC] + + +## 安装准备 + +### mysql 初始配置 + +数据文件目录:/var/lib/mysql + +* 安装完成后,调整 mysql 服务的配置参数 + + 查看当前配置:show variables; + + 最大连接数 max_connections + 操作日志的保留时长 binlog_expire_logs_seconds + + 参考命令: + ``` + set global max_connections = 1000; + set persist max_connections = 1000; + + // 7天 86400 * 7 + // 1天 86400 + set global binlog_expire_logs_seconds = 86400 * 7; + set persist binlog_expire_logs_seconds = 86400 * 7; + ``` + + 时区设置 + + 确保MySQL 的时区设置为 GMT+8 + + +* 创建数据库帐号 + + 参考命令: + ``` + create user 'user'@'%' identified with mysql_native_password by 'your_password'; + ``` + + +* 创建 database + + ``` + user + user_authz + cas_server + token_server + personal_security_center + + agent_service + communicate_center + + admin_center + + tmp_data + ``` + + 参考命令: + ``` + create database `user` DEFAULT CHARSET utf8 COLLATE utf8_general_ci; + ``` + +* 授予权限 + + 将 database 的权限授予对应的帐号 + + 参考命令: + ``` + grant all privileges on `user`.* to 'user'@'%' with grant option; + ``` + + +* 授予 SUPER 权限 + 由于 部分帐号 需要创建 触发器,故,需要 SUPER 权限 + 涉及帐号有 user、user_authz、cas_server + + 参考命令: + ``` + grant SUPER on *.* to 'user'@'%'; + grant SUPER on *.* to 'user_authz'@'%'; + grant SUPER on *.* to 'cas_server'@'%'; + + grant SUPER on *.* to 'tmp_data'@'%'; + ``` + + +* 备份与还原 + + 参考命令: + 备份: + ``` + mysqldump -u root -p cas_server > cas_server.sql + mysqldump -u root -p token_server > token_server.sql + mysqldump -u root -p user > user.sql + mysqldump -u root -p user_authz > user_authz.sql + mysqldump -u root -p admin_center > admin_center.sql + mysqldump -u root -p personal_security_center > personal_security_center.sql + mysqldump -u root -p agent_service > agent_service.sql + mysqldump -u root -p communicate_center > communicate_center.sql + ``` + + 还原: + ``` + mysql -u root -p cas_server < cas_server.sql + mysql -u root -p token_server < token_server.sql + mysql -u root -p user < user.sql + mysql -u root -p user_authz < user_authz.sql + mysql -u root -p admin_center < admin_center.sql + mysql -u root -p personal_security_center < personal_security_center.sql + mysql -u root -p agent_service < agent_service.sql + mysql -u root -p communicate_center < communicate_center.sql + ``` + + +* 创建交换帐号 + + **待部署完成后操作** + + 如果,存在数据交换 须将组织机构数据、帐号数据 同步到用户服务的数据库的 + 则,需要创建一个 交换用的数据库帐号(user_trans),并为该帐号授予 表 user.TMP_ORGANIZATION_ORIGIN、user.TMP_ACCOUNT_ORIGIN 的读写操作的权限 + + 参考命令: + ``` + create user 'user_trans'@'%' identified with mysql_native_password by 'your_password'; + + grant select on `user`.`TMP_ORGANIZATION_ORIGIN` to 'user_trans'@'%'; + grant insert on `user`.`TMP_ORGANIZATION_ORIGIN` to 'user_trans'@'%'; + grant update on `user`.`TMP_ORGANIZATION_ORIGIN` to 'user_trans'@'%'; + grant delete on `user`.`TMP_ORGANIZATION_ORIGIN` to 'user_trans'@'%'; + + grant select on `user`.`TMP_ACCOUNT_ORIGIN` to 'user_trans'@'%'; + grant insert on `user`.`TMP_ACCOUNT_ORIGIN` to 'user_trans'@'%'; + grant update on `user`.`TMP_ACCOUNT_ORIGIN` to 'user_trans'@'%'; + grant delete on `user`.`TMP_ACCOUNT_ORIGIN` to 'user_trans'@'%'; + + grant select on `user`.`TMP_ORGANIZATION_TRANS` to 'user_trans'@'%'; + grant insert on `user`.`TMP_ORGANIZATION_TRANS` to 'user_trans'@'%'; + grant update on `user`.`TMP_ORGANIZATION_TRANS` to 'user_trans'@'%'; + grant delete on `user`.`TMP_ORGANIZATION_TRANS` to 'user_trans'@'%'; + + grant select on `user`.`TMP_ACCOUNT_TRANS` to 'user_trans'@'%'; + grant insert on `user`.`TMP_ACCOUNT_TRANS` to 'user_trans'@'%'; + grant update on `user`.`TMP_ACCOUNT_TRANS` to 'user_trans'@'%'; + grant delete on `user`.`TMP_ACCOUNT_TRANS` to 'user_trans'@'%'; + ``` + + +### harbor 准备 + +* 创建 devops 帐号 + + 用于 rancher 部署时拉取镜像 + + 用户管理 下 创建用户 + 如 devops + + +* 镜像同步 + + 从 https://harbor.supwisdom.com 中同步镜像 + + 仓库管理 下 新建目标 + ``` + supwisdom https://harbor.supwisdom.com rancher.devops / PWMgP85qiLFC + ``` + + 同步管理 下 新建规则 + + ``` + admin-portal admin-portal/* + authx-service authx-service/* + + thirdparty-agent-service thirdparty-agent-service/* + user-data-service goa/* + user-authorization-service user-authorization-service/* + cas-server cas-server/* + token-server token-server/* + communicate-center communicate-center/* + jobs-server jobs-server/* + + personal-security-center personal-security-center/* + admin-center admin-center/* + + admin-platform admin-platform/* + ``` + + 同步规则,创建完成后,进行镜像同步 + + 选择某个同步规则,点击 同步,等待任务完成 + + +* 授予 devops 帐号 对各个项目的 访客 权限 + + 项目 下,点击 项目名称,进入到 成员,添加用户,查找用户 devops,选择角色 访客,确定,添加即可 + + +### rancher 准备 + +* 创建项目 + + 进入 全局 - 集群(具体名称视项目安装而定) - 项目/命名空间,添加项目 + + 输入 项目名称,保存 + + +* 创建命名空间 + + 进入 全局 - 集群(具体名称视项目安装而定) - 项目/命名空间 + + 在新建的项目中,添加命名空间 + + 输入 名称,保存 + +* 导入YAML + + 进入 全局 - 集群(具体名称视项目安装而定) - 项目(某个项目) + + 进入 资源 - 工作负载 + + +### 域名准备 + +* 确定域名 + + 首先明确是否使用泛域名,如:`*.paas.xxx.edu.cn`,或 直接使用学校域名 `xxx.edu.cn` + + 本产品安装需要的域名如下: + ``` + cas.paas.xxx.edu.cn 认证(视具体情况,可调整) + token.paas.xxx.edu.cn 认证(APP适用) + + personal-security-center.paas.xxx.edu.cn 个人安全中心后端API + + security-center.paas.xxx.edu.cn 安全中心前端UI(帐号激活、忘记密码) + + admin-center.paas.xxx.edu.cn 云平台后端API + + admin-platform.paas.xxx.edu.cn 云平台前端UI + ``` + + 如果使用 学校域名,则去除 .paas 即可,同时申请开通相关域名 + + +## 开始安装 + + +### 数据库创建 + +* 数据库帐号 + + 服务 | 帐号 + - | - + 用户服务 user-data-service | user + 授权服务 user-authorization-service | user_authz + 认证服务 cas-server | cas_server + 认证服务(APP适用) token-server | token_server + - | - + 第三方代理服务 thridparty-agent-service | agent_service + 通信服务 communicate-center | communicate_center + - | - + 管理中心 admin-center | admin_center + - | - + v4认证迁移数据 | tmp_data + + 创建命令 + + **请修改命令中的 `your_password` 为实际的数据库帐号的密码** + ``` + create user 'user'@'%' identified with mysql_native_password by 'your_password'; + create user 'user_authz'@'%' identified with mysql_native_password by 'your_password'; + create user 'cas_server'@'%' identified with mysql_native_password by 'your_password'; + create user 'token_server'@'%' identified with mysql_native_password by 'your_password'; + + create user 'agent_service'@'%' identified with mysql_native_password by 'your_password'; + create user 'communicate_center'@'%' identified with mysql_native_password by 'your_password'; + + create user 'admin_center'@'%' identified with mysql_native_password by 'your_password'; + + create user 'tmp_data'@'%' identified with mysql_native_password by 'your_password'; + ``` + + + + +### rancher 容器部署 + +* 修改 yaml 中的相关配置 + + 具体参考 yaml 文件中的说明 + + + 0.infras + + 基础设施,目前包含 MySQL数据库的Web管理端、SpringBoot服务的管理端 + + ``` + 0.0.0.infras-base.yaml 请修改 harbor-registry 的帐号密码 + + 0.0.1.infras-mysql.yaml 请修改 MySQL数据库 的地址、IP,mysql-adminer 访问域名 + + 0.0.2.infras-sba.yaml 请修改 docker 镜像地址 + + ``` + + + 1.authx-service + + 业务中台 之 认证授权服务 + + 参考 yaml 中的说明,修改相关配置 + + ``` + 在各个服务的安装脚本目录下,修改以下文件(若存在)中的配置 + 0.*-base.yaml 请修改 harbor-registry 的帐号密码 + + 4.x.*.yaml, 5.*-datax-job.yaml 请修改 docker 镜像地址 + + 1.*-env.yaml, 5.*-datax-job.yaml 请修改 数据库密码 + + 2.*-ingresses.yaml 请修改 访问域名 + + + 0.0.trans-service-v4 + + 此为 认证v4 的数据迁移服务(可选) + + 将 认证v4 的数据导入到 tmp_data 下 + + 数据迁移后,还需要手动编写脚本,将数据迁移至 用户服务、授权服务 的数据库中 + + + 0.authx-service + + 此为 公共基础服务 + + 如:MySQL 服务地址(Endpoints)、文件存储服务 + + 1.authx-service-mysql.yaml + + 请修改 mysql 的服务地址 IP + + 2.authx-service-minio.yaml + + 请修改 minio 的 `MINIO_ACCESS_KEY`、`MINIO_SECRET_KEY` + + 根据情况修改 pvc 的 storageClassName + + + 9.poa-api-docs_install.yaml + + 用于将 认证授权服务的 poa 接口文档,导入到 poa-sa 中,**请在 poa 安装完成后处理** + + 请修改 poa 的服务地址 `POA_SERVER_URL` + + + 1.thirdparty-agent-service + + 此为 第三方服务的代理服务 + + file-minio + + 修改 minio 的 `FILE_MINIO_ACCESSKEY`、`FILE_MINIO_SECRETKEY` + + mail-smtp + + 获取 学校的 smtp 服务地址,邮箱帐号,用于发送邮件 + + sms-aliyun + + 如果 学校使用 阿里云的短信服务,提供 `ACCESS_KEY_ID`、`ACCESS_SECRET`; + 否则,提供相关的短信平台,进行定制开发 + + + 2.user-data-service + + 此为 用户服务 + + goa + + 如果 须将用户数据的变更下发到 Openldap 等第三方业务中,则须配置 `JOBS_RABBITMQ_*` 为开启(ENABLED=true) + + + 3.user-authorization-service + + 此为 授权服务 + + + 4.cas-server + + 此为 认证服务 + + cas-server-site-webapp + + 生成公私钥证书,参考 certs/jwt/readme.md 生成公私钥pem,修改相关配置 `CASSERVER_JWT_PRIVATE_KEY_PEM_PKCS8`、`CASSERVER_JWT_PUBLIC_KEY_PEM` + + 修改 认证服务的外网访问地址 `CAS_SERVER_NAME` + + 修改 CAT TGC 的安全,若 使用 https,则须修改 `CAS_TGC_SECURE: "true"` + + 修改 安全中心(帐号激活、找回密码)的链接地址 `CASSERVERSITE_FORGOT_PASSWORD_URL`、`CASSERVERSITE_ACTIVE_ACCOUNT_URL` + + 联合登录(QQ、微信、企业微信、支付宝等)配置 `CASSERVER_FEDERATION_*` + + 动态密码认证 相关配置 + 1. 短信模板(动态密码) `CASSERVERSITE_PASSWORDLESS_SMS_TEXT_TEMPLATE` + 2. 短信接口地址 `TPAS_AGENT_SERVICE_SMS_SENDER_PATH` + + 如果 须与 超级APP 对接,须修改 Token 验签公钥地址 `SUPERAPP_TOKEN_SIGNING_KEY_URL` + + 如果 须开启图片验证码,修改 `CASSERVERSITE_CAPTCHA_ENABLED: "true"` + + + 5.token-server + + 此为 认证服务(适用于APP,可选) + + token-server + + 生成公私钥证书(与cas-server保持一致),参考 certs/jwt/readme.md 生成公私钥pem,修改相关配置 `TOKEN_SERVER_SECURITY_JWT_PRIVATE_KEY_PEM_PKCS8`、`TOKEN_SERVER_SECURITY_JWT_PUBLIC_KEY_PEM` + + 修改 认证服务的外网访问地址 `TOKEN_SERVER_PREFIX` + + 修改 认证服务 Id-Token 的签发者标识 `TOKEN_SERVER_SECURITY_JWT_ISS` + + 动态密码认证 相关配置(与cas-server保持一致) + 1. 短信模板(动态密码) `TOKEN_SERVER_PASSWORDLESS_SMS_TEXT_TEMPLATE` + 2. 短信接口地址 `TPAS_AGENT_SERVICE_SMS_SENDER_PATH` + + 人脸认证,须配置人脸服务,目前支持 新开普人脸服务、百度人脸服务,根据情况获取相关配置参数 + + APP 登录信息 个推,使用了消息服务的接口,该接口由 POA 提供,故须 + 1. 注册 POA client,获取 `clientId`、`clientSecret`,申请 Scope `messagecenter:v1:sendMessage` + 2. 获取 消息服务的 `appId` + + + 6.personal-security-center + + 此为 个人安全中心 后端API,安全中心 前端UI + + 提供个人帐号相关的操作的接口,以及 帐号激活、密码找回 等功能 + + + + TODO: 修改 bff、zuul 配置 + TODO: 修改 security-center-ui 配置 + + + 9.jobs-server + + 此为 任务调度服务 + + 基于 定时任务、触发任务 等,完成 用户数据的同步 + + 如: + * 源头数据进入到临时表后,写入用户的正式表 + * 用户数据更新后,通过消息队列,增量更新 Openldap 数据 + + + + ``` + + + 6.admin-platform + + 云平台 + + ``` + + 6.admin-center + + 此为 云平台 后端API + + + 7.admin-platform + + 此为 云平台 前端UI + + ``` + + +* 添加项目、命名空间 + + 项目 + ``` + infras # 基础设施(可选,方便实施工作) + + authx-service # 认证授权服务 + + admin-platform # 管理平台 + + ``` + + 命名空间 + + 在项目 infras 下创建 命名空间: + + ``` + base + + ``` + + 在项目 authx-service 下创建 命名空间: + + ``` + trans-service(认证v4的数据迁移服务,可选) + + authx-service + + thirdparty-agent-service + + user-data-service + + user-authorization-service + + cas-server + + token-server + + personal-security-center + + communicate-center + + jobs-server + + ``` + + 在项目 admin-platform 下创建 命名空间: + + ``` + admin-center + + admin-platform + + ``` + + +* 导入YAML + + 在项目 infras 中,将 0.infras 下的 yaml 按编号依次导入 + + ``` + 0.0.0.infras-base.yaml + + 0.0.1.infras-mysql.yaml mysql web管理 + + 0.0.2.infras-sba.yaml + + ``` + + 在项目 authx-service 中,将 1.authx-service 下的 yaml 按编号依次导入 + + 务必确保 `4.0.*-installer.yaml` 执行成功 + + + 在项目 admin-platform 中,将 6.admin-platform 下的 yaml 按编号依次导入 + + +### 数据配置 + + 数据脚本初始化 + + 先修改 脚本中的域名(如果存在) + + +* 可选,1.authx-service/10.0.tmp.sql + + 若通过交换同步组织机构、帐号数据的,须执行该数据库脚本 + + +* 可选,1.authx-service/10.1.init-flow.sql + + 若部署了 流程平台 的产品 + + 可默认创建几个管理员帐号,以及初始授权 + + +* **必选,6.admin-platform/10.0.init.sql** + + 修改 数据库数据初始化时的默认配置 + + +* 可选,6.admin-platform/10.1.init-flow.sql + + 若部署了 流程平台 的产品 + + 将 流程平台 的管理菜单 添加到 云平台中 diff --git "a/project/newcapec-test/k8s-rancher/0.1.1.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\345\256\211\350\243\205\351\203\250\347\275\262\346\211\213\345\206\214.pdf" "b/project/newcapec-test/k8s-rancher/0.1.1.\350\256\244\350\257\201\346\216\210\346\235\203\346\234\215\345\212\241\345\256\211\350\243\205\351\203\250\347\275\262\346\211\213\345\206\214.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..de752a8e4552138e37b32a79cb2fbb0ba04e2f73 GIT binary patch literal 146441 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%0D>NPu<~CvVn3lso&(bYd{j({s{+r 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 literal 0 HcmV?d00001 diff --git "a/project/newcapec-test/k8s-rancher/0.2.1.POA\357\274\210\345\271\263\345\217\260OpenAPI\357\274\211\346\234\215\345\212\241\346\263\250\345\206\214.md" "b/project/newcapec-test/k8s-rancher/0.2.1.POA\357\274\210\345\271\263\345\217\260OpenAPI\357\274\211\346\234\215\345\212\241\346\263\250\345\206\214.md" new file mode 100644 index 0000000..5dcbbb6 --- /dev/null +++ "b/project/newcapec-test/k8s-rancher/0.2.1.POA\357\274\210\345\271\263\345\217\260OpenAPI\357\274\211\346\234\215\345\212\241\346\263\250\345\206\214.md" @@ -0,0 +1,7 @@ + +# POA(平台OpenAPI)服务注册 + +**请确保POA已经安装完成** + +根据 9.poa-api-docs 下的 readme.md 的说明进行操作 + diff --git "a/project/newcapec-test/k8s-rancher/0.2.2.\347\237\255\344\277\241\345\271\263\345\217\260\345\257\271\346\216\245\350\257\264\346\230\216.md" "b/project/newcapec-test/k8s-rancher/0.2.2.\347\237\255\344\277\241\345\271\263\345\217\260\345\257\271\346\216\245\350\257\264\346\230\216.md" new file mode 100644 index 0000000..b786222 --- /dev/null +++ "b/project/newcapec-test/k8s-rancher/0.2.2.\347\237\255\344\277\241\345\271\263\345\217\260\345\257\271\346\216\245\350\257\264\346\230\216.md" @@ -0,0 +1,14 @@ +# 短信平台对接说明 + + +## 阿里云短信服务 + +须申请阿里云短信服务 + +参考 docs 下的 《阿里云短信申请(签名、模板)》 + + +## 第三方短信平台 + +须进行定制开发 + diff --git a/project/newcapec-test/k8s-rancher/0.infras/0.0.0.infras-base.yaml b/project/newcapec-test/k8s-rancher/0.infras/0.0.0.infras-base.yaml new file mode 100644 index 0000000..12b0340 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/0.infras/0.0.0.infras-base.yaml @@ -0,0 +1,17 @@ +# 0.0.0.infras-base.yaml + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: base + name: harbor-registry +data: + # 修改harbor仓库配置 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 + diff --git a/project/newcapec-test/k8s-rancher/0.infras/0.0.1.infras-mysql.yaml b/project/newcapec-test/k8s-rancher/0.infras/0.0.1.infras-mysql.yaml new file mode 100644 index 0000000..fd62f7d --- /dev/null +++ b/project/newcapec-test/k8s-rancher/0.infras/0.0.1.infras-mysql.yaml @@ -0,0 +1,102 @@ +# 0.0.1.infras-mysql.yaml + +# 此服务可选安装,用于MySQL数据库的管理提供Web端 + +#################################################### +# mysql-server +#################################################### +--- +apiVersion: v1 +kind: Service +metadata: + namespace: base + name: mysql-server +spec: + ports: + - name: tcp-mysql + port: 3306 + protocol: TCP + targetPort: 3306 +--- +kind: Endpoints +apiVersion: v1 +metadata: + namespace: base + name: mysql-server +subsets: + - addresses: + # 修改实际MySQL服务器的IP地址 + - ip: 172.30.104.82 + ports: + - name: tcp-mysql + port: 3306 + protocol: TCP + + +#################################################### +# mysql-adminer +#################################################### +--- +apiVersion: v1 +kind: Service +metadata: + namespace: base + name: mysql-adminer +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: http + selector: + app: mysql-adminer + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: base + name: mysql-adminer +spec: + selector: + matchLabels: + app: mysql-adminer + replicas: 1 + template: + metadata: + labels: + app: mysql-adminer + spec: + containers: + - name: mysql-adminer + image: adminer:4 + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + env: + - name: ADMINER_DEFAULT_SERVER + value: mysql-server + resources: + requests: + memory: "512Mi" + limits: + memory: "512Mi" + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: mysql-adminer-ingress + namespace: base +spec: + rules: + # 修改为学校的根域名 + - host: mysql-adminer.paas.xxx.edu.cn + http: + paths: + - path: / + backend: + serviceName: mysql-adminer + servicePort: http + diff --git a/project/newcapec-test/k8s-rancher/0.infras/0.0.2.infras-sba.yaml b/project/newcapec-test/k8s-rancher/0.infras/0.0.2.infras-sba.yaml new file mode 100644 index 0000000..70b3269 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/0.infras/0.0.2.infras-sba.yaml @@ -0,0 +1,117 @@ +# 0.0.2.infras-sba.yaml + +# 此服务可选安装,用于开发人员排查问题 + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: base + name: spring-boot-admin-env-secret +data: + # sbaadmin + SBA_USERNAME: c2JhYWRtaW4= + # sbanimda + SBA_PASSWORD: c2JhbmltZGE= + + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: base + name: spring-boot-admin-env +data: + SERVER_PORT: "8080" + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: base + name: spring-boot-admin-svc + labels: + app: spring-boot-admin + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: spring-boot-admin +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: base + name: spring-boot-admin +spec: + selector: + matchLabels: + app: spring-boot-admin + replicas: 1 + template: + metadata: + labels: + app: spring-boot-admin + spec: + containers: + - name: spring-boot-admin + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/institute/spring-boot-admin:0.1.0-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - secretRef: + name: spring-boot-admin-env-secret + - configMapRef: + name: spring-boot-admin-env + resources: + requests: + memory: "400Mi" + limits: + memory: "400Mi" + readinessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: sba-ingress + namespace: base +spec: + rules: + # 修改为学校的根域名 + - host: sba.paas.xxx.edu.cn + http: + paths: + - path: / + backend: + serviceName: spring-boot-admin-svc + servicePort: http + diff --git a/project/newcapec-test/k8s-rancher/0.infras/0.0.x.infras-monitor.yaml b/project/newcapec-test/k8s-rancher/0.infras/0.0.x.infras-monitor.yaml new file mode 100644 index 0000000..88c23c2 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/0.infras/0.0.x.infras-monitor.yaml @@ -0,0 +1,21 @@ +# + +# 此配置可选安装,用于配置监控 + +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: authx-service-monitor + namespace: cattle-prometheus +spec: + selector: + matchLabels: + needMonitor: 'true' + namespaceSelector: + matchNames: + - user-data-service + - user-authorization-service + - cas-server + endpoints: + - port: http-metrics + path: /metrics diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/0.trans-service-v4-base.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/0.trans-service-v4-base.yaml new file mode 100644 index 0000000..e37e2d5 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/0.trans-service-v4-base.yaml @@ -0,0 +1,47 @@ +# 0.trans-service-v4-base.yaml + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: trans-service + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 + + +#################################################### +# mysql-server +#################################################### +--- +apiVersion: v1 +kind: Service +metadata: + namespace: trans-service + name: mysql-server +spec: + ports: + - name: tcp-mysql + port: 3306 + protocol: TCP + targetPort: 3306 +--- +kind: Endpoints +apiVersion: v1 +metadata: + namespace: trans-service + name: mysql-server +subsets: + - addresses: + # 修改实际MySQL服务器的IP地址 + - ip: 172.30.104.82 + ports: + - name: tcp-mysql + port: 3306 + protocol: TCP diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/1.trans-service-v4-env.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/1.trans-service-v4-env.yaml new file mode 100644 index 0000000..7c65b68 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/1.trans-service-v4-env.yaml @@ -0,0 +1,26 @@ +# 1.trans-service-v4-env.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: trans-service + name: jvm-env +data: + MAX_RAM_PERCENTAGE: "75.0" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: trans-service + name: datasource-env-secret +type: Opaque +data: + # jdbc:mysql://mysql-server.authx-service.svc.cluster.local:3306/tmp_data?serverTimezone=Asia/Shanghai + JDBC_URL: amRiYzpteXNxbDovL215c3FsLXNlcnZlci5hdXRoeC1zZXJ2aWNlLnN2Yy5jbHVzdGVyLmxvY2FsOjMzMDYvdG1wX2RhdGE/c2VydmVyVGltZXpvbmU9QXNpYS9TaGFuZ2hhaQ== + # tmp_data + JDBC_USERNAME: dG1wX2RhdGE= + # 修改为实际的数据库密码,并使用 base64 工具进行编码 + # kingstar + JDBC_PASSWORD: a2luZ3N0YXI= diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/4.0.trans-service-v4-installer.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/4.0.trans-service-v4-installer.yaml new file mode 100644 index 0000000..7a14465 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/4.0.trans-service-v4-installer.yaml @@ -0,0 +1,46 @@ +# 4.0.trans-service-v4-installer.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: trans-service + name: trans-installer-env +data: + DB_TYPE: mysql8 + + +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: trans-installer + namespace: trans-service +spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: trans-installer + spec: + restartPolicy: Never + containers: + - name: trans-installer + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/admin-portal/trans-installer:1.0.0-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: trans-installer-env + resources: + requests: + memory: "256Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/5.trans-service-v4-datax-job.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/5.trans-service-v4-datax-job.yaml new file mode 100644 index 0000000..62581c7 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/0.0.trans-service-v4/5.trans-service-v4-datax-job.yaml @@ -0,0 +1,55 @@ +# 5.trans-service-v4-datax-job.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: trans-service + name: trans-datax-job-env +data: + EANBLED_JOBS: TMP_DM_GENDER,TMP_DM_ORGTYPE,TMP_DM_ACCOUNTTYPE,TMP_DM_IDENTITYTYPE,TMP_ORGANIZE,TMP_PERSON,TMP_ACCOUNT,TMP_REGISTERED_SERVICE,TMP_WEAK_PASSWORD_DICT,TMP_TB_ORGANIZE,TMP_TB_USER,TMP_TB_ACCOUNT,TMP_TB_USERGROUP,TMP_TB_ROLE,TMP_TB_APPLICATION,TMP_TB_FUNCTION,TMP_TB_RIGHT,TMP_TB_ACCOUNTSECURITYEMAIL,TMP_TB_ACCOUNTSECURITYMOBILE,TMP_REF_ORGANIZEUSER,TMP_REF_USERGROUPACCOUNT,TMP_REF_ACCOUNTROLE,TMP_REF_USERGROUPROLE,TMP_REF_USERROLE,TMP_REF_APPLICATIONROLE,TMP_REF_FUNCTIONROLE,TMP_REF_RIGHTROLE + + ORACLEREADER_UNIAUTH_USERNAME: idc_u_uniauth + ORACLEREADER_UNIAUTH_PASSWORD: kingstar + ORACLEREADER_UNIAUTH_JDBC_URL: jdbc:oracle:thin:@172.30.104.101:1521/xydb + + MYSQLWRITER8_TMP_USERNAME: tmp_data + MYSQLWRITER8_TMP_PASSWORD: kingstar + MYSQLWRITER8_TMP_JDBC_URL: jdbc:mysql://mysql-server:3306/tmp_data + + +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: trans-datax-job + namespace: trans-service +spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: trans-datax-job + spec: + restartPolicy: Never + containers: + - name: trans-datax-job + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/admin-portal/trans-datax-job:1.0.0-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: trans-datax-job-env + resources: + # requests: + # memory: "400Mi" + # limits: + # memory: "400Mi" + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/0.authx-service-base.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/0.authx-service-base.yaml new file mode 100644 index 0000000..cb85dba --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/0.authx-service-base.yaml @@ -0,0 +1,16 @@ +# 0.authx-service-base.yaml + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: authx-service-test + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/1.authx-service-mysql.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/1.authx-service-mysql.yaml new file mode 100644 index 0000000..7a59dc3 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/1.authx-service-mysql.yaml @@ -0,0 +1,32 @@ +# 0.0.1.authx-service-mysql.yaml + +#################################################### +# mysql-server +# 外部 MySQL 的服务地址映射 +#################################################### +--- +apiVersion: v1 +kind: Service +metadata: + namespace: authx-service-test + name: mysql-server +spec: + ports: + - name: tcp-mysql + port: 3306 + protocol: TCP + targetPort: 3306 +--- +kind: Endpoints +apiVersion: v1 +metadata: + namespace: authx-service-test + name: mysql-server +subsets: + - addresses: + # 修改实际MySQL服务器的IP地址 + - ip: 192.168.116.91 + ports: + - name: tcp-mysql + port: 3306 + protocol: TCP diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/2.authx-service-minio.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/2.authx-service-minio.yaml new file mode 100644 index 0000000..3b757fb --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/2.authx-service-minio.yaml @@ -0,0 +1,115 @@ +# 2.authx-service-minio.yaml + +#################################################### +# minio +# 文件服务器,对象存储 +#################################################### + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + namespace: authx-service-test + name: minio-data-pvc +spec: + accessModes: + - ReadWriteMany + # 根据情况修改 + storageClassName: supwisdom-nfs-storage + resources: + requests: + storage: 5Gi + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: authx-service-test + name: minio-env-secret +type: Opaque +data: + # 修改 access_key,并使用 base64 工具进行编码 + # 默认值:1y8N@8R@a_2u + MINIO_ACCESS_KEY: MXk4TkA4UkBhXzJ1 + # 修改 secret_key,并使用 base64 工具进行编码 + # 默认至:8pxlIe9#lN7Q + MINIO_SECRET_KEY: OHB4bEllOSNsTjdR + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: authx-service-test + name: minio-svc + labels: + app: minio +spec: + ports: + - port: 9000 + targetPort: http + protocol: TCP + name: http + selector: + app: minio +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: authx-service-test + name: minio +spec: + selector: + matchLabels: + app: minio + replicas: 1 + template: + metadata: + labels: + app: minio + spec: + containers: + - name: minio + image: minio/minio:RELEASE.2020-04-23T00-58-49Z + imagePullPolicy: Always + args: + - "server" + - "/data" + ports: + - containerPort: 9000 + name: http + envFrom: + - secretRef: + name: minio-env-secret + volumeMounts: + - mountPath: /data + name: minio-data + resources: + requests: + memory: "256Mi" + limits: + memory: "256Mi" + volumes: + - name: minio-data + persistentVolumeClaim: + claimName: minio-data-pvc + + +# 该 ingress 配置可选,主要用于实施调试用 +# --- +# apiVersion: extensions/v1beta1 +# kind: Ingress +# metadata: +# name: minio-ingress +# namespace: authx-service +# spec: +# rules: +# # 修改为学校的根域名 +# - host: minio.paas.xxx.edu.cn +# http: +# paths: +# - path: / +# backend: +# serviceName: minio-svc +# servicePort: http + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/8.echo-server.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/8.echo-server.yaml new file mode 100644 index 0000000..0c2de7e --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/8.echo-server.yaml @@ -0,0 +1,58 @@ +# 8.echo-server.yaml + +# 用于环境测试 + +--- +apiVersion: v1 +kind: Service +metadata: + name: echo-server + namespace: default + labels: + run: echo-server +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 8080 + protocol: TCP + name: http + selector: + run: echo-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: echo-server + namespace: default +spec: + selector: + matchLabels: + run: echo-server + replicas: 1 + template: + metadata: + labels: + run: echo-server + spec: + containers: + - name: echo-server + # 若使用了学校搭设的私有仓库,请修改 + image: inanimate/echo-server:latest + ports: + - containerPort: 8080 +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: echo-server-ingress + namespace: default +spec: + rules: + # **修改** 学校的根域名 + - host: echo.paas.xxx.edu.cn + http: + paths: + - backend: + serviceName: echo-server + servicePort: 80 diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/9.poa-api-docs-installer.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/9.poa-api-docs-installer.yaml new file mode 100644 index 0000000..4b24f61 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/0.authx-service/9.poa-api-docs-installer.yaml @@ -0,0 +1,47 @@ +# 10.9.poa-api-docs-installer.yaml + +# 安装完 POA 后,执行 + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: authx-service-test + name: poa-api-docs-installer-env +data: + ## + # 平台OpenAPI的外网访问地址, + # **修改** 学校的根域名 + POA_SERVER_URL: http://poa.paas.xxx.edu.cn + + +--- +apiVersion: batch/v1 +kind: Job +metadata: + namespace: authx-service-test + name: poa-api-docs-installer +spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: poa-api-docs-installer + spec: + restartPolicy: Never + containers: + - name: poa-api-docs-installer + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/authx-service/poa-api-docs-installer:1.0.0-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: poa-api-docs-installer-env + resources: + requests: + memory: "256Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/0.thirdparty-agent-service-base.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/0.thirdparty-agent-service-base.yaml new file mode 100644 index 0000000..053cea8 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/0.thirdparty-agent-service-base.yaml @@ -0,0 +1,16 @@ +# thirdparty-agent-service-base.yaml + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: thirdparty-agent-service-test + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/1.thirdparty-agent-service-env.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/1.thirdparty-agent-service-env.yaml new file mode 100644 index 0000000..8ad8c6e --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/1.thirdparty-agent-service-env.yaml @@ -0,0 +1,26 @@ +# thirdparty-agent-service-env.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: thirdparty-agent-service-test + name: jvm-env +data: + MAX_RAM_PERCENTAGE: "75.0" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: thirdparty-agent-service-test + name: datasource-env-secret +type: Opaque +data: + # jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/agent_service?serverTimezone=Asia/Shanghai + SPRING_DATASOURCE_URL: amRiYzpteXNxbDovL215c3FsLXNlcnZlci5hdXRoeC1zZXJ2aWNlLXRlc3Quc3ZjLmNsdXN0ZXIubG9jYWw6MzMwNi9hZ2VudF9zZXJ2aWNlP3NlcnZlclRpbWV6b25lPUFzaWEvU2hhbmdoYWk= + # agent_service + SPRING_DATASOURCE_USERNAME: YWdlbnRfc2VydmljZQ== + # 修改为实际的数据库密码,并使用 base64 工具进行编码 + # Nwpu@Supwisdom123 + SPRING_DATASOURCE_PASSWORD: TndwdUBTdXB3aXNkb20xMjM= diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/4.2.thirdparty-agent-service.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/4.2.thirdparty-agent-service.yaml new file mode 100644 index 0000000..a9b3341 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/1.thirdparty-agent-service/4.2.thirdparty-agent-service.yaml @@ -0,0 +1,149 @@ +# thirdparty-agent-service.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: thirdparty-agent-service-test + name: agent-service-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + + SERVER_MAXHTTPHEADERSIZE: "10240" + + # SERVER_TOMCAT_ACCEPT_COUNT: "1000" + # SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + # SERVER_TOMCAT_MAX_THREADS: "1000" + # SERVER_TOMCAT_MIN_SPARE_THREADS: "10" + + ## file-db + FILE_DB_AUTOCONFIGURE_ENABLED: "false" + + ## file-minio + FILE_MINIO_AUTOCONFIGURE_ENABLED: "true" + FILE_MINIO_ENDPOINT: http://minio-svc.authx-service-test.svc.cluster.local:9000 + # FILE_MINIO_ACCESSKEY: "" + # FILE_MINIO_SECRETKEY: "" + + ## mail-console + MAIL_CONSOLE_AUTOCONFIGURE_ENABLED: "true" + + # 若须对接邮件服务,须提供 SMTP 帐号 + ## mail-smtp + MAIL_SMTP_AUTOCONFIGURE_ENABLED: "false" + MAIL_SMTP_HOST: smtp.mxhichina.com + MAIL_SMTP_PORT: "25" + MAIL_SMTP_SECURE_MODE: NONE + MAIL_SMTP_USERNAME: security.institute@supwisdom.com + MAIL_SMTP_PASSWORD: Security2019 + MAIL_SMTP_FROM: security.institute@supwisdom.com + MAIL_SMTP_FROM_PERSONAL: 智慧校园 + + ## sms-console + SMS_CONSOLE_AUTOCONFIGURE_ENABLED: "true" + + # 若须使用阿里云短信服务,须提供帐号 + ## sms-aliyun + SMS_ALIYUN_AUTOCONFIGURE_ENABLED: "false" + SMS_ALIYUN_REGION_ID: cn-hangzhou + SMS_ALIYUN_ACCESS_KEY_ID: "" + SMS_ALIYUN_ACCESS_SECRET: "" + + # 若须对接sms 接口,须进行二开定制 + + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: thirdparty-agent-service-test + name: agent-service-env-secret +type: Opaque +data: + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_PASSWORD: "" + + ## file-minio + FILE_MINIO_ACCESSKEY: MXk4TkA4UkBhXzJ1 + # 1y8N@8R@a_2u + FILE_MINIO_SECRETKEY: OHB4bEllOSNsTjdR + # 8pxlIe9#lN7Q + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: thirdparty-agent-service-test + name: agent-service-svc + labels: + app: agent-service + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: agent-service + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: thirdparty-agent-service-test + name: agent-service +spec: + selector: + matchLabels: + app: agent-service + replicas: 1 + template: + metadata: + labels: + app: agent-service + spec: + containers: + - name: agent-service + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/thirdparty-agent-service/agent-service:0.0.1-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - secretRef: + name: agent-service-env-secret + - configMapRef: + name: agent-service-env + resources: + requests: + memory: "512Mi" + limits: + memory: "512Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/10.0.init.sql b/project/newcapec-test/k8s-rancher/1.authx-service/10.0.init.sql new file mode 100644 index 0000000..42cfae0 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/10.0.init.sql @@ -0,0 +1,102 @@ +-- 10.0.init.sql + + +use cas_server; + + +INSERT INTO `TB_SERVICE` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `NAME`, `DESCRIPTION`, `INFORMATION_URL`, `LOGOUT_URL`, + `RESPONSE_TYPE`, `LOGOUT_TYPE`, + `EVALUATION_ORDER`, `FRIENDLY_NAME`, `REGISTERED_SERVICE_ID`, `SERVICE_ID`, + `ENABLED`, `SSO_ENABLED`, `REQUIRE_ALL_ATTRIBUTES`, + `APPLICATION_ID`, `EXTERNAL_ID`) +VALUES ('122', '1', 0, 'admin', '2020-07-01 00:00:00', + '安全中心-test', '安全中心-test', 'https://security-center.paas.example.com', 'https://security-center.paas.example.com/logout', + 'REDIRECT', 'FRONT_CHANNEL', + 122, '安全中心-test', 122, 'https://security-center.paas.example.com/(.*)', + 1, 1, 1, + '122', '122'); + +commit; + + +-- 修改根域名 +update TB_SERVICE +set + INFORMATION_URL='https://security-center-test.paas.newcapec.cn', + LOGOUT_URL='https://security-center-test.paas.newcapec.cn/logout', + SERVICE_ID='https://security-center-test.paas.newcapec.cn/(.*)', + ID_TOKEN_ENABLED=1, + JWT_AS_SERVICE_TICKET=1, + APPLICATION_DOMAIN='security-center.paas.newcapec.cn' +where ID='122'; -- todo, modify + +commit; + + + + +use user; + +-- **配置 身份对应的帐号 须自动关联的 用户组** + +/* + +IDENTITY_TYPE + +1 admin 系统用户 + +T01 T01 教职工 + +S01 S01 本科生 +S02 S02 研究生 +S03 S03 非学历生 + +P01 P01 聘用人员 +P02 P02 外聘教师 +P99 P99 在职/企业博士后 + + +GROUP + +11 teacher 教职工用户组 +12 student 本科生用户组 +13 graduate 研究生用户组 +14 fellow 校友用户组 + +16 admin 管理人员用户组 +17 retire 退休用户组 + +010883e0ac5e11eaaaee297ae5eef932 bsh 在职/企业博士后 + +23f87450ac5e11eaaaee297ae5eef932 wpjs 外聘教师 +f1e42c20ac5d11eaaaee297ae5eef932 pyry 聘用人员 + +ffa610e0ac6111eaaaee297ae5eef932 fxls 非学历生用户组 + +*/ + + +insert into TB_B_IDENTITY_TYPE_GROUP_INITIAL (ID, DELETED, ADD_ACCOUNT, IDENTITY_TYPE_ID, GROUP_ID) +values ('1', 0, 'init', 'T01', '11'); + +insert into TB_B_IDENTITY_TYPE_GROUP_INITIAL (ID, DELETED, ADD_ACCOUNT, IDENTITY_TYPE_ID, GROUP_ID) +values ('2', 0, 'init', 'S01', '12'); + +insert into TB_B_IDENTITY_TYPE_GROUP_INITIAL (ID, DELETED, ADD_ACCOUNT, IDENTITY_TYPE_ID, GROUP_ID) +values ('3', 0, 'init', 'S02', '13'); + +insert into TB_B_IDENTITY_TYPE_GROUP_INITIAL (ID, DELETED, ADD_ACCOUNT, IDENTITY_TYPE_ID, GROUP_ID) +values ('4', 0, 'init', 'S03', 'ffa610e0ac6111eaaaee297ae5eef932'); + +insert into TB_B_IDENTITY_TYPE_GROUP_INITIAL (ID, DELETED, ADD_ACCOUNT, IDENTITY_TYPE_ID, GROUP_ID) +values ('5', 0, 'init', 'P01', 'f1e42c20ac5d11eaaaee297ae5eef932'); + +insert into TB_B_IDENTITY_TYPE_GROUP_INITIAL (ID, DELETED, ADD_ACCOUNT, IDENTITY_TYPE_ID, GROUP_ID) +values ('6', 0, 'init', 'P02', '23f87450ac5e11eaaaee297ae5eef932'); + +insert into TB_B_IDENTITY_TYPE_GROUP_INITIAL (ID, DELETED, ADD_ACCOUNT, IDENTITY_TYPE_ID, GROUP_ID) +values ('7', 0, 'init', 'P99', '010883e0ac5e11eaaaee297ae5eef932'); + +commit; + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/10.0.tmp.sql b/project/newcapec-test/k8s-rancher/1.authx-service/10.0.tmp.sql new file mode 100644 index 0000000..b7aaa52 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/10.0.tmp.sql @@ -0,0 +1,206 @@ + +/* + * 若通过交换同步组织机构、帐号数据的,须执行该数据库脚本 + */ + +use user; + +/* + +delete from TB_B_ACCOUNT_ORGANIZATION where ADD_ACCOUNT='trans'; + +delete from TB_B_SAFETY where ADD_ACCOUNT='trans'; +delete from TB_B_ACCOUNT where ADD_ACCOUNT='trans'; +delete from TB_B_USER where ADD_ACCOUNT='trans'; + +delete from TMP_ACCOUNT_TRANS; + +update TMP_ACCOUNT_ORIGIN set UID=UID; +*/ + + +DROP TRIGGER IF EXISTS after_update_organization_origin; + +delimiter // +create trigger after_update_organization_origin after update on TMP_ORGANIZATION_ORIGIN for each row +begin + declare ID1 varchar(100); + declare ID2 varchar(100); + + -- new 代表 表中新增的数据 + set ID1 = (select ID from TMP_ORGANIZATION_TRANS + where ((ID is null and new.ID is null) or ID=new.ID) + and ((PARENT_ORGANIZATION_ID is null and new.PARENT_ORGANIZATION_ID is null) or PARENT_ORGANIZATION_ID=new.PARENT_ORGANIZATION_ID) + and ((CODE is null and new.CODE is null) or CODE=new.CODE) + and ((NAME is null and new.NAME is null) or NAME=new.NAME) + and ((DESCRIPTION is null and new.DESCRIPTION is null) or DESCRIPTION=new.DESCRIPTION) + and ((TYPE_ID is null and new.TYPE_ID is null) or TYPE_ID=new.TYPE_ID) + and ((STATE is null and new.STATE is null) or STATE=new.STATE) + and ((ENABLE is null and new.ENABLE is null) or ENABLE=new.ENABLE) + and ((IS_DATA_CENTER is null and new.IS_DATA_CENTER is null) or IS_DATA_CENTER=new.IS_DATA_CENTER) + ); + -- into @ID1; + + if ID1 is null then + set ID2 = (select ID from TMP_ORGANIZATION_TRANS where ID=new.ID); -- into @ID2; + + if ID2 is null then + insert into TMP_ORGANIZATION_TRANS(TRANS_STATUS, TRANS_TIME, PROC_STATUS, PROC_TIME, + ID, PARENT_ORGANIZATION_ID, + CODE, NAME, DESCRIPTION, + TYPE_ID, + STATE, ENABLE, + IS_DATA_CENTER + ) + values ('1', now(), '0', null, + new.ID, new.PARENT_ORGANIZATION_ID, + new.CODE, new.NAME, new.DESCRIPTION, + new.TYPE_ID, + new.STATE, new.ENABLE, + new.IS_DATA_CENTER + ) + ; + + else + update TMP_ORGANIZATION_TRANS set + TRANS_STATUS='2', + TRANS_TIME=now(), + PROC_STATUS='0', + PARENT_ORGANIZATION_ID=new.PARENT_ORGANIZATION_ID, + CODE=new.CODE, + NAME=new.NAME, + DESCRIPTION=new.DESCRIPTION, + TYPE_ID=new.TYPE_ID, + STATE=new.STATE, + ENABLE=new.ENABLE, + IS_DATA_CENTER=new.IS_DATA_CENTER + where ID=new.ID + ; + + end if; + + else + + -- 如果数据没变化,但存在记录,且被处理,则标记未 不更新、不处理 + update TMP_ORGANIZATION_TRANS set + TRANS_STATUS='0', + TRANS_TIME=now(), + PROC_STATUS='0' + where ID=new.ID + and PROC_RESULT!='0' + ; + + end if; + +end // +delimiter ; + + +DROP TRIGGER IF EXISTS after_update_account_origin; + +delimiter // +create trigger after_update_account_origin after update on TMP_ACCOUNT_ORIGIN for each row +begin + declare ID1 varchar(100); + declare ID2 varchar(100); + + -- new 代表 表中新增的数据 + set ID1 = (select ID from TMP_ACCOUNT_TRANS + where ((ID is null and new.ID is null) or ID=new.ID) + and ((UID is null and new.UID is null) or UID=new.UID) + and ((NAME is null and new.NAME is null) or NAME=new.NAME) + and ((NAME_SPELLING is null and new.NAME_SPELLING is null) or NAME_SPELLING=new.NAME_SPELLING) + and ((FULL_NAME_SPELLING is null and new.FULL_NAME_SPELLING is null) or FULL_NAME_SPELLING=new.FULL_NAME_SPELLING) + and ((CERTIFICATE_TYPE_ID is null and new.CERTIFICATE_TYPE_ID is null) or CERTIFICATE_TYPE_ID=new.CERTIFICATE_TYPE_ID) + and ((CERTIFICATE_NUMBER is null and new.CERTIFICATE_NUMBER is null) or CERTIFICATE_NUMBER=new.CERTIFICATE_NUMBER) + and ((PHONE_NUMBER is null and new.PHONE_NUMBER is null) or PHONE_NUMBER=new.PHONE_NUMBER) + and ((EMAIL is null and new.EMAIL is null) or EMAIL=new.EMAIL) + and ((IMAGE_URL is null and new.IMAGE_URL is null) or IMAGE_URL=new.IMAGE_URL) + and ((GENDER_ID is null and new.GENDER_ID is null) or GENDER_ID=new.GENDER_ID) + and ((NATION_ID is null and new.NATION_ID is null) or NATION_ID=new.NATION_ID) + and ((COUNTRY_ID is null and new.COUNTRY_ID is null) or COUNTRY_ID=new.COUNTRY_ID) + and ((ADDRESS_ID is null and new.ADDRESS_ID is null) or ADDRESS_ID=new.ADDRESS_ID) + and ((ACCOUNT_NAME is null and new.ACCOUNT_NAME is null) or ACCOUNT_NAME=new.ACCOUNT_NAME) + and ((ACCOUNT_EXPIRY_DATE is null and new.ACCOUNT_EXPIRY_DATE is null) or ACCOUNT_EXPIRY_DATE=new.ACCOUNT_EXPIRY_DATE) + and ((ORGANIZATION_ID is null and new.ORGANIZATION_ID is null) or ORGANIZATION_ID=new.ORGANIZATION_ID) + and ((IDENTITY_TYPE_ID is null and new.IDENTITY_TYPE_ID is null) or IDENTITY_TYPE_ID=new.IDENTITY_TYPE_ID) + and ((ACTIVATION is null and new.ACTIVATION is null) or ACTIVATION=new.ACTIVATION) + and ((STATE is null and new.STATE is null) or STATE=new.STATE) + and ((IS_DATA_CENTER is null and new.IS_DATA_CENTER is null) or IS_DATA_CENTER=new.IS_DATA_CENTER) + ); + -- into @ID1; + + if ID1 is null then + set ID2 = (select ID from TMP_ACCOUNT_TRANS where ID=new.ID); -- into @ID2; + + if ID2 is null then + insert into TMP_ACCOUNT_TRANS(TRANS_STATUS, TRANS_TIME, PROC_STATUS, PROC_TIME, + ID, UID, + NAME, NAME_SPELLING, FULL_NAME_SPELLING, + CERTIFICATE_TYPE_ID, CERTIFICATE_NUMBER, + PHONE_NUMBER, EMAIL, + IMAGE_URL, + GENDER_ID, NATION_ID, COUNTRY_ID, ADDRESS_ID, + ACCOUNT_NAME, ACCOUNT_EXPIRY_DATE, ORGANIZATION_ID, IDENTITY_TYPE_ID, + ACTIVATION, STATE, + IS_DATA_CENTER + ) + values ('1', now(), '0', null, + new.ID, new.UID, + new.NAME, new.NAME_SPELLING, new.FULL_NAME_SPELLING, + new.CERTIFICATE_TYPE_ID, new.CERTIFICATE_NUMBER, + new.PHONE_NUMBER, new.EMAIL, + new.IMAGE_URL, + new.GENDER_ID, new.NATION_ID, new.COUNTRY_ID, new.ADDRESS_ID, + new.ACCOUNT_NAME, new.ACCOUNT_EXPIRY_DATE, new.ORGANIZATION_ID, new.IDENTITY_TYPE_ID, + new.ACTIVATION, new.STATE, + new.IS_DATA_CENTER + ) + ; + + else + update TMP_ACCOUNT_TRANS set + TRANS_STATUS='2', + TRANS_TIME=now(), + PROC_STATUS='0', + UID=new.UID, + NAME=new.NAME, + NAME_SPELLING=new.NAME_SPELLING, + FULL_NAME_SPELLING=new.FULL_NAME_SPELLING, + CERTIFICATE_TYPE_ID=new.CERTIFICATE_TYPE_ID, + CERTIFICATE_NUMBER=new.CERTIFICATE_NUMBER, + PHONE_NUMBER=new.PHONE_NUMBER, + EMAIL=new.EMAIL, + IMAGE_URL=new.IMAGE_URL, + GENDER_ID=new.GENDER_ID, + NATION_ID=new.NATION_ID, + COUNTRY_ID=new.COUNTRY_ID, + ADDRESS_ID=new.ADDRESS_ID, + ACCOUNT_NAME=new.ACCOUNT_NAME, + ACCOUNT_EXPIRY_DATE=new.ACCOUNT_EXPIRY_DATE, + ORGANIZATION_ID=new.ORGANIZATION_ID, + IDENTITY_TYPE_ID=new.IDENTITY_TYPE_ID, + ACTIVATION=new.ACTIVATION, + STATE=new.STATE, + IS_DATA_CENTER=new.IS_DATA_CENTER + where ID=new.ID + ; + + end if; + + else + + -- 如果数据没变化,但存在记录,且被处理,则标记未 不更新、不处理 + update TMP_ACCOUNT_TRANS set + TRANS_STATUS='0', + TRANS_TIME=now(), + PROC_STATUS='0' + where ID=new.ID + and PROC_RESULT!='0' + ; + + end if; + +end // +delimiter ; + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/10.0.trans.sql b/project/newcapec-test/k8s-rancher/1.authx-service/10.0.trans.sql new file mode 100644 index 0000000..784af9b --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/10.0.trans.sql @@ -0,0 +1,73 @@ +-- 10.0.trans.sql + +/* + 脚本用于 认证v4 的数据迁移 +*/ + +--执行前 TB_B_USER.UID 加索引 + + + +-- 更新老认证的密码 +UPDATE user.TB_B_USER u, ( + select ACCOUNT_NAME, case when ENCODED_PASSWORD is null then PASSWORD else ENCODED_PASSWORD end as PASSWORD + from tmp_data.TMP_ACCOUNT +) a +SET u.PASSWORD = a.PASSWORD +WHERE u.UID = a.ACCOUNT_NAME + + + +-- 更新激活状态 +update user.TB_B_ACCOUNT a, ( + select TB_B_USER.ID from tmp_data.TMP_ACCOUNT + inner join user.TB_B_USER on TMP_ACCOUNT.ACCOUNT_NAME=TB_B_USER.UID + where TMP_ACCOUNT.IS_ACTIVATED=1 +) tmp +set a.ACTIVATION=1 +where a.USER_ID=tmp.ID + + + +-- 更新老认证的安全邮箱 +update user.TB_B_SAFETY s, ( + select TB_B_USER.ID, TMP_TB_ACCOUNTSECURITYEMAIL.EMAILACCOUNTID as ACCOUNTID, EMAILINFO + from tmp_data.TMP_TB_ACCOUNTSECURITYEMAIL + inner join tmp_data.TMP_TB_ACCOUNT on TMP_TB_ACCOUNTSECURITYEMAIL.EMAILACCOUNTID=TMP_TB_ACCOUNT.ACCOUNTKEY + inner join user.TB_B_USER on TMP_TB_ACCOUNT.ACCOUNTKEY=TB_B_USER.UID + where EMAILINFO is not null and EMAILINFO!='' and EMAILINFO!='-1' and EMAILSTATUS in ('已验证', '待修改') +) email +set s.SECURE_EMAIL=email.EMAILINFO +where s.USER_ID=email.ID +; + +-- 更新老认证的安全手机 +update user.TB_B_SAFETY s, ( + select TB_B_USER.ID, TMP_TB_ACCOUNTSECURITYMOBILE.MOBILEACCOUNTID as ACCOUNTID, MOBILEINFO + from tmp_data.TMP_TB_ACCOUNTSECURITYMOBILE + inner join tmp_data.TMP_TB_ACCOUNT on TMP_TB_ACCOUNTSECURITYMOBILE.MOBILEACCOUNTID=TMP_TB_ACCOUNT.ACCOUNTKEY + inner join user.TB_B_USER on TMP_TB_ACCOUNT.ACCOUNTKEY=TB_B_USER.UID + where MOBILEINFO is not null and MOBILEINFO!='' and MOBILEINFO!='-1' and MOBILESTATUS in ('已验证', '待修改') +) mobile +set s.SECURE_PHONE=mobile.MOBILEINFO +where s.USER_ID=mobile.ID +; + + + + +-- 迁移 微信 绑定信息 +insert into cas_server.TB_FEDERATION (ID, COMPANY_ID, DELETED, ADD_ACCOUNT, USER_NO, FEDERATED_TYPE, FEDERATED_ID) +select ID, '1', 0, 'trans', + ACCOUNT_NAME, 'openweixin', WECHAT_UNIONID +from tmp_data.TMP_ACCOUNT_WECHAT +; + + +-- 迁移 QQ 绑定信息 +insert into cas_server.TB_FEDERATION (ID, COMPANY_ID, DELETED, ADD_ACCOUNT, USER_NO, FEDERATED_TYPE, FEDERATED_ID) +select ID, '1', 0, 'trans', + ACCOUNT_NAME, 'qq', QQ_OPENID +from tmp_data.TMP_ACCOUNT_QQ +; + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-flow.sql b/project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-flow.sql new file mode 100644 index 0000000..4b1a696 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-flow.sql @@ -0,0 +1,122 @@ +-- 10.1.init.sql + +/* +将 paas.example.com 替换为 paas.学校域名.edu.cn +*/ + + +-- 以下脚本为可选操作 + +/* + * 若部署了流程平台、门户的产品 + * 可默认创建几个管理员帐号,以及初始授权 + */ + + +-- 创建管理帐号 + +use user; + +-- flowadmin +INSERT INTO `TB_B_USER` (`ID`, `DELETED`, + `UID`, `PASSWORD`, `NAME`, `NAME_SPELLING`, `FULL_NAME_SPELLING`, + `CERTIFICATE_TYPE_ID`, `CERTIFICATE_NUMBER`, `PHONE_NUMBER`, `EMAIL`, + `GENDER_ID`, `NATION_ID`, `COUNTRY_ID`, `ADDRESS_ID`) +VALUES ('50', 0, + '50', 'flowadmin', '流程表单管理员', 'flowadmin', 'flowadmin', + '20001', '50', null, 'flowadmin@supwisdom.com', + '30001', '40001', '50156', '310000'); + +INSERT INTO `TB_B_ACCOUNT` (`ID`, `DELETED`, `USER_ID`, + `ACCOUNT_NAME`, `ACCOUNT_EXPIRY_DATE`, `ORGANIZATION_ID`, `IDENTITY_TYPE_ID`, + `ACTIVATION`, `STATE`, `IS_DATA_CENTER`) +VALUES ('50', 0, '50', + 'flowadmin', null, '1', '1', + 1, 'NORMAL', 0); + +INSERT INTO `TB_B_SAFETY`(`ID`, `DELETED`, `USER_ID`, `SCORE`, `PASSWORD_SCORE`, `SECURE_EMAIL`, `SECURE_PHONE`) +VALUES ('50', 0, '50', '0', '0', null, null); + +INSERT INTO `TB_B_ACCOUNT_ORGANIZATION` (`ID`, `DELETED`, + `ROOT_ORGANIZATION_ID`, `ACCOUNT_ID`, `ORGANIZATION_ID`) +VALUES ('50_1', 0, + '0', '50', '1'); + +INSERT INTO `TB_B_ACCOUNT_LABEL`(`ID`, `DELETED`, + `ACCOUNT_ID`, `LABEL_ID`) +VALUES ('50_1', 0, '50', '1'); + +commit; + + +-- 创建管理帐号的授权 + +use user_authz; + +-- flow +INSERT INTO `TB_ROLE` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, `APPLICATION_ID`, `CODE`, `NAME`, `DESCRIPTION`, `ENABLED`, `EXTERNAL_ID`) +VALUES ('50', '1', 0, 'admin', '2019-07-01 00:00:00', '1', 'flow-admin', '流程管理员', '流程管理员', 1, '50'); +INSERT INTO `TB_ROLE` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, `APPLICATION_ID`, `CODE`, `NAME`, `DESCRIPTION`, `ENABLED`, `EXTERNAL_ID`) +VALUES ('51', '1', 0, 'admin', '2019-07-01 00:00:00', '1', 'flow-biz', '流程业务员', '流程业务员', 1, '51'); + +INSERT INTO `TB_GRANTED_ACCOUNT_ROLE` (`ID`, `COMPANY_ID`, `DELETED`, + `ACCOUNT_ID`, `ROLE_ID`, + `GRANT_EXPIRED_DATE`) +VALUES ('50_50', '1', 0, + '50', '50', + NULL); + +INSERT INTO `TB_ROLE_USER` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `ORIGIN_TYPE`, `ORIGIN_PK`, + `APPLICATION_ID`, `ROLE_ID`, `ACCOUNT_ID`, + `GRANT_EXPIRED_DATE`) +VALUES ('50_50', '1', 0, 'admin', '2019-07-01 00:00:00', + NULL, NULL, + '1', '50', '50', + NULL); + +commit; + + +-- 创建认证帐号、认证对接 + +use cas_server; + +-- flow + +INSERT INTO `TB_ACCOUNT` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `USERNAME`, `PASSWORD`, `DESCRIPTION`, `ENABLED`, `ACCOUNT_NON_EXPIRED`, `ACCOUNT_NON_LOCKED`, `CREDENTIALS_NON_EXPIRED`, + `IDENTITY`, `USER_NO`, `NAME`, `MOBILE`, `EMAIL_ADDRESS`, `IDENTITY_TYPE`, `IDENTITY_NO`, + `EXTERNAL_ID`) +VALUES ('50', '1', 0, 'admin', '2019-07-01 00:00:00', + 'flowadmin', 'flowadmin', '流程管理员', 1, 1, 1, 1, + 'admin', '50', '流程管理员', '', 'flowadmin@supwisdom.com', '20001', '', + '50'); + +commit; + +INSERT INTO `TB_SERVICE` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `NAME`, `DESCRIPTION`, `INFORMATION_URL`, `LOGOUT_URL`, + `RESPONSE_TYPE`, `LOGOUT_TYPE`, + `EVALUATION_ORDER`, `FRIENDLY_NAME`, `REGISTERED_SERVICE_ID`, `SERVICE_ID`, + `ENABLED`, `SSO_ENABLED`, `REQUIRE_ALL_ATTRIBUTES`, + `APPLICATION_ID`, `EXTERNAL_ID`) +VALUES ('50', '1', 0, 'admin', '2019-07-01 00:00:00', + '流程平台', '流程平台', 'https://formflow.paas.example.com', 'https://formflow.paas.example.com/formflow/cas/authen/logout', + 'REDIRECT', 'FRONT_CHANNEL', + 50, '流程平台', 50, 'https://formflow.paas.example.com/(.*)', + 1, 1, 1, + '50', '50'); + +commit; + +update TB_SERVICE +set + INFORMATION_URL='http://formflow.paas.example.com', + LOGOUT_URL='http://formflow.paas.example.com/formflow/cas/authen/logout', + SERVICE_ID='http://formflow.paas.example.com/(.*)', + ID_TOKEN_ENABLED=1 +where ID='50'; -- todo, modify + +commit; + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-message.sql b/project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-message.sql new file mode 100644 index 0000000..f69dbfe --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-message.sql @@ -0,0 +1,78 @@ +-- 10.1.init-message.sql + +/* +将 paas.example.com 替换为 paas.学校域名.edu.cn +*/ + + +-- 以下脚本为可选操作 + +/* + * 若部署了消息服务产品 + * 可默认创建几个管理员帐号,以及初始授权 + */ + + +-- 创建管理帐号 + +use user; + +-- messageadmin +INSERT INTO `TB_B_USER` (`ID`, `DELETED`, + `UID`, `PASSWORD`, `NAME`, `NAME_SPELLING`, `FULL_NAME_SPELLING`, + `CERTIFICATE_TYPE_ID`, `CERTIFICATE_NUMBER`, `PHONE_NUMBER`, `EMAIL`, + `GENDER_ID`, `NATION_ID`, `COUNTRY_ID`, `ADDRESS_ID`) +VALUES ('80', 0, + '80', 'messageadmin', '流程表单管理员', 'messageadmin', 'messageadmin', + '20001', '80', null, 'messageadmin@supwisdom.com', + '30001', '40001', '50156', '310000'); + +INSERT INTO `TB_B_ACCOUNT` (`ID`, `DELETED`, `USER_ID`, + `ACCOUNT_NAME`, `ACCOUNT_EXPIRY_DATE`, `ORGANIZATION_ID`, `IDENTITY_TYPE_ID`, + `ACTIVATION`, `STATE`, `IS_DATA_CENTER`) +VALUES ('80', 0, '80', + 'messageadmin', null, '1', '1', + 1, 'NORMAL', 0); + +INSERT INTO `TB_B_SAFETY`(`ID`, `DELETED`, `USER_ID`, `SCORE`, `PASSWORD_SCORE`, `SECURE_EMAIL`, `SECURE_PHONE`) +VALUES ('80', 0, '80', '0', '0', null, null); + +INSERT INTO `TB_B_ACCOUNT_ORGANIZATION` (`ID`, `DELETED`, + `ROOT_ORGANIZATION_ID`, `ACCOUNT_ID`, `ORGANIZATION_ID`) +VALUES ('80_1', 0, + '0', '80', '1'); + +INSERT INTO `TB_B_ACCOUNT_LABEL`(`ID`, `DELETED`, + `ACCOUNT_ID`, `LABEL_ID`) +VALUES ('80_1', 0, '80', '1'); + +commit; + + +-- 创建管理帐号的授权 + +use user_authz; + +-- message +INSERT INTO `TB_ROLE` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, `APPLICATION_ID`, `CODE`, `NAME`, `DESCRIPTION`, `ENABLED`, `EXTERNAL_ID`) +VALUES ('80', '1', 0, 'admin', '2020-07-01 00:00:00', '1', 'message-admin', '消息平台管理员', '消息平台管理员', 1, '80'); +INSERT INTO `TB_ROLE` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, `APPLICATION_ID`, `CODE`, `NAME`, `DESCRIPTION`, `ENABLED`, `EXTERNAL_ID`) +VALUES ('81', '1', 0, 'admin', '2020-07-01 00:00:00', '1', 'message-opt', '消息平台操作员', '消息平台操作员', 1, '81'); + +INSERT INTO `TB_GRANTED_ACCOUNT_ROLE` (`ID`, `COMPANY_ID`, `DELETED`, + `ACCOUNT_ID`, `ROLE_ID`, + `GRANT_EXPIRED_DATE`) +VALUES ('80_80', '1', 0, + '80', '80', + NULL); + +INSERT INTO `TB_ROLE_USER` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `ORIGIN_TYPE`, `ORIGIN_PK`, + `APPLICATION_ID`, `ROLE_ID`, `ACCOUNT_ID`, + `GRANT_EXPIRED_DATE`) +VALUES ('80_80', '1', 0, 'admin', '2019-07-01 00:00:00', + NULL, NULL, + '1', '80', '80', + NULL); + +commit; diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-portal.sql b/project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-portal.sql new file mode 100644 index 0000000..61b09d4 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/10.1.init-portal.sql @@ -0,0 +1,140 @@ +-- 10.1.init.sql + +/* +将 paas.example.com 替换为 paas.学校域名.edu.cn +*/ + + +-- 以下脚本为可选操作 + +/* + * 若部署了流程平台、门户的产品 + * 可默认创建几个管理员帐号,以及初始授权 + */ + + +-- 创建管理帐号 + +use user; + +-- portaladmin +INSERT INTO `TB_B_USER` (`ID`, `DELETED`, + `UID`, `PASSWORD`, `NAME`, `NAME_SPELLING`, `FULL_NAME_SPELLING`, + `CERTIFICATE_TYPE_ID`, `CERTIFICATE_NUMBER`, `PHONE_NUMBER`, `EMAIL`, + `GENDER_ID`, `NATION_ID`, `COUNTRY_ID`, `ADDRESS_ID`) +VALUES ('60', 0, + '60', 'portaladmin', '门户管理员', 'portaladmin', 'portaladmin', + '20001', '60', null, 'portaladmin@supwisdom.com', + '30001', '40001', '50156', '310000'); + +INSERT INTO `TB_B_ACCOUNT` (`ID`, `DELETED`, `USER_ID`, + `ACCOUNT_NAME`, `ACCOUNT_EXPIRY_DATE`, `ORGANIZATION_ID`, `IDENTITY_TYPE_ID`, + `ACTIVATION`, `STATE`, `IS_DATA_CENTER`) +VALUES ('60', 0, '60', + 'portaladmin', null, '1', '1', + 1, 'NORMAL', 0); + +INSERT INTO `TB_B_SAFETY`(`ID`, `DELETED`, `USER_ID`, `SCORE`, `PASSWORD_SCORE`, `SECURE_EMAIL`, `SECURE_PHONE`) +VALUES ('60', 0, '60', '0', '0', null, null); + +INSERT INTO `TB_B_ACCOUNT_ORGANIZATION` (`ID`, `DELETED`, + `ROOT_ORGANIZATION_ID`, `ACCOUNT_ID`, `ORGANIZATION_ID`) +VALUES ('60_1', 0, + '0', '60', '1'); + +INSERT INTO `TB_B_ACCOUNT_LABEL`(`ID`, `DELETED`, + `ACCOUNT_ID`, `LABEL_ID`) +VALUES ('60_1', 0, '60', '1'); + +commit; + + +-- 创建管理帐号的授权 + +use user_authz; + +-- portal +INSERT INTO `TB_SYSTEM` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `BUSINESS_DOMAIN_ID`, + `CODE`, `NAME`, `DESCRIPTION`, `ENABLED`) +VALUES ('60', '1', 0, 'admin', '2019-07-01 00:00:00', + '1', + 'portal', '门户', '门户', 1); + +INSERT INTO `TB_APPLICATION` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `BUSINESS_DOMAIN_ID`, `SYSTEM_ID`, + `NAME`, `APPLICATION_ID`, `SYNC_URL`, `ENABLED`) +VALUES ('60', '1', 0, 'admin', '2019-07-01 00:00:00', + '1', '60', + '门户', '60', '', 1); + +INSERT INTO `TB_ROLE` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `APPLICATION_ID`, `CODE`, `NAME`, `DESCRIPTION`, `ENABLED`, `EXTERNAL_ID`) +VALUES ('60', '1', 0, 'admin', '2019-07-01 00:00:00', + '60', 'portal-admin', '门户管理员', '门户管理员', 1, '60'); + +INSERT INTO `TB_ROLE_USER` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `ORIGIN_TYPE`, `ORIGIN_PK`, + `APPLICATION_ID`, `ROLE_ID`, `ACCOUNT_ID`, + `GRANT_EXPIRED_DATE`) +VALUES ('60_60_60', '1', 0, 'admin', '2019-07-01 00:00:00', + NULL, NULL, + '60', '60', '60', + NULL); + +commit; + + +-- 配置门户角色的同步接口 + +update TB_APPLICATION +set + SYNC_URL='http://portal.paas.example.com/portal-web/api/open/role/findAll' +where ID='60'; -- todo, modify + +commit; + + +-- 创建认证帐号、认证对接 + +use cas_server; + +-- portal + +INSERT INTO `TB_ACCOUNT` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `USERNAME`, `PASSWORD`, `DESCRIPTION`, `ENABLED`, `ACCOUNT_NON_EXPIRED`, `ACCOUNT_NON_LOCKED`, `CREDENTIALS_NON_EXPIRED`, + `IDENTITY`, `USER_NO`, `NAME`, `MOBILE`, `EMAIL_ADDRESS`, `IDENTITY_TYPE`, `IDENTITY_NO`, + `EXTERNAL_ID`) +VALUES ('60', '1', 0, 'admin', '2019-07-01 00:00:00', + 'portaladmin', 'portaladmin', '门户管理员', 1, 1, 1, 1, + 'admin', '60', '门户管理员', '', 'portaladmin@supwisdom.com', '20001', '', + '60'); + +commit; + + +INSERT INTO `TB_SERVICE` (`ID`, `COMPANY_ID`, `DELETED`, `ADD_ACCOUNT`, `ADD_TIME`, + `NAME`, `DESCRIPTION`, `INFORMATION_URL`, `LOGOUT_URL`, + `RESPONSE_TYPE`, `LOGOUT_TYPE`, + `EVALUATION_ORDER`, `FRIENDLY_NAME`, `REGISTERED_SERVICE_ID`, `SERVICE_ID`, + `ENABLED`, `SSO_ENABLED`, `REQUIRE_ALL_ATTRIBUTES`, + `APPLICATION_ID`, `EXTERNAL_ID`) +VALUES ('60', '1', 0, 'admin', '2019-07-01 00:00:00', + '门户', '门户', 'https://ecampus.paas.example.com', 'https://ecampus.paas.example.com/cas/slo', + 'REDIRECT', 'FRONT_CHANNEL', + 60, '门户', 60, 'https://ecampus.paas.example.com/login', + 1, 1, 1, + '60', '60'); + +commit; + +update TB_SERVICE +set + INFORMATION_URL='http://ecampus.paas.example.com', + LOGOUT_URL='http://ecampus.paas.example.com/cas/slo', + SERVICE_ID='http://ecampus.paas.example.com/cas/(.*)', + ID_TOKEN_ENABLED=1 +where ID='60'; -- todo, modify + +commit; + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/0.user-data-service-base.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/0.user-data-service-base.yaml new file mode 100644 index 0000000..474a9ec --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/0.user-data-service-base.yaml @@ -0,0 +1,213 @@ +# user-data-service-base.yaml + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: user-data-service-test + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 + + +#################################################### +# redis-server +#################################################### +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app: redis + release: redis-server + name: redis-server + namespace: user-data-service-test +type: Opaque +data: + REDIS_PASSWORD: OEt1d29zbE9pdXc3SA== +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: redis + release: redis-server + name: redis-server + namespace: user-data-service-test +spec: + ports: + - name: redis + port: 6379 + protocol: TCP + targetPort: redis + selector: + app: redis + release: redis-server + role: master + type: ClusterIP +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: redis + release: redis-server + name: redis-server + namespace: user-data-service-test +spec: + podManagementPolicy: OrderedReady + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: redis + release: redis-server + role: master + serviceName: redis-master + template: + metadata: + labels: + app: redis + release: redis-server + role: master + spec: + containers: + - name: redis-server + env: + - name: REDIS_DISABLE_COMMANDS + value: FLUSHDB,FLUSHALL + - name: REDIS_REPLICATION_MODE + value: master + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-server + key: REDIS_PASSWORD + # 若使用了学校搭设的私有仓库,请修改 + image: bitnami/redis:4.0 + # 若使用了学校搭设的私有仓库,请修改 为 Always + imagePullPolicy: IfNotPresent + # imagePullPolicy: Always + livenessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - containerPort: 6379 + name: redis + protocol: TCP + readinessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 5 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + volumeMounts: + - mountPath: /bitnami/redis/data + name: redis-data + dnsPolicy: ClusterFirst + restartPolicy: Always + securityContext: + fsGroup: 1001 + # runAsUser: 1001 + # https://github.com/bitnami/bitnami-docker-redis/issues/106#issuecomment-388884372 + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - emptyDir: {} + name: redis-data + # 若使用了学校搭设的私有仓库,请增加以下配置(取消注释即可) + # imagePullSecrets: + # - name: harbor-registry + updateStrategy: + rollingUpdate: + partition: 0 + type: RollingUpdate + + + +#################################################### +# rabbitmq-server +#################################################### +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app: rabbitmq + release: rabbitmq-server + name: rabbitmq-server + namespace: user-data-service-test +type: Opaque +data: + RABBITMQ_USERNAME: Z3Vlc3Q= + RABBITMQ_PASSWORD: Z3Vlc3Q= +--- +apiVersion: v1 +kind: Service +metadata: + name: rabbitmq-server + namespace: user-data-service-test + labels: + app: rabbitmq-server +spec: + ports: + - port: 5672 + targetPort: tcp-1 + protocol: TCP + name: tcp-1 + - port: 15672 + targetPort: tcp-2 + protocol: TCP + name: tcp-2 + selector: + app: rabbitmq-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: rabbitmq-server + namespace: user-data-service-test +spec: + selector: + matchLabels: + app: rabbitmq-server + replicas: 1 + template: + metadata: + labels: + app: rabbitmq-server + annotations: + sidecar.istio.io/inject: "false" + spec: + containers: + - name: rabbitmq-server + # 若使用了学校搭设的私有仓库,请修改 + image: rabbitmq:management + # 若使用了学校搭设的私有仓库,请修改 为 Always + imagePullPolicy: IfNotPresent + # imagePullPolicy: Always + ports: + - containerPort: 5672 + name: tcp-1 + - containerPort: 15672 + name: tcp-2 + # 若使用了学校搭设的私有仓库,请增加以下配置(取消注释即可) + # imagePullSecrets: + # - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/1.user-data-service-env.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/1.user-data-service-env.yaml new file mode 100644 index 0000000..00ccef7 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/1.user-data-service-env.yaml @@ -0,0 +1,52 @@ +# user-data-service-env.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-data-service-test + name: jvm-env +data: + MAX_RAM_PERCENTAGE: "75.0" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: user-data-service-test + name: datasource-env-secret +type: Opaque +data: + # jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user?serverTimezone=Asia/Shanghai + JDBC_URL: amRiYzpteXNxbDovL215c3FsLXNlcnZlci5hdXRoeC1zZXJ2aWNlLXRlc3Quc3ZjLmNsdXN0ZXIubG9jYWw6MzMwNi91c2VyP3NlcnZlclRpbWV6b25lPUFzaWEvU2hhbmdoYWk= + # user + JDBC_USERNAME: dXNlcg== + # 修改为实际的数据库密码,并使用 base64 工具进行编码 + # Nwpu@Supwisdom123 + JDBC_PASSWORD: TndwdUBTdXB3aXNkb20xMjM= + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: user-data-service-test + name: redis-env-secret +type: Opaque +data: + SPRING_REDIS_HOST: cmVkaXMtc2VydmVy + SPRING_REDIS_PORT: NjM3OQ== + SPRING_REDIS_PASSWORD: OEt1d29zbE9pdXc3SA== + + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: user-data-service-test + name: rabbitmq-env-secret +type: Opaque +data: + SPRING_RABBITMQ_HOST: cmFiYml0bXEtc2VydmVy + SPRING_RABBITMQ_PORT: NTY3Mg== + SPRING_RABBITMQ_USERNAME: Z3Vlc3Q= + SPRING_RABBITMQ_PASSWORD: Z3Vlc3Q= diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/2.user-data-service-ingresses.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/2.user-data-service-ingresses.yaml new file mode 100644 index 0000000..30ad33a --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/2.user-data-service-ingresses.yaml @@ -0,0 +1,20 @@ +# user-data-service-ingresses.yaml + +# 暂时不使用,直接使用内部地址 +# --- +# apiVersion: extensions/v1beta1 +# kind: Ingress +# metadata: +# namespace: user-data-service-test +# name: user-api-ingress +# spec: +# rules: +# # 修改为学校的根域名 +# - host: user-api.paas.xxx.edu.cn +# http: +# paths: +# - path: / +# backend: +# serviceName: user-data-service-poa-svc +# servicePort: http + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.0.user-data-service-installer.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.0.user-data-service-installer.yaml new file mode 100644 index 0000000..46b78db --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.0.user-data-service-installer.yaml @@ -0,0 +1,46 @@ +# user-data-service-installer.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-data-service-test + name: user-data-service-installer-env +data: + DB_TYPE: mysql8 + + +--- +apiVersion: batch/v1 +kind: Job +metadata: + namespace: user-data-service-test + name: user-data-service-installer +spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: user-data-service-installer + spec: + restartPolicy: Never + containers: + - name: user-data-service-installer + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/goa/installer:0.1.1-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: user-data-service-installer-env + resources: + requests: + memory: "256Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.1.user-data-service-poa.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.1.user-data-service-poa.yaml new file mode 100644 index 0000000..6121637 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.1.user-data-service-poa.yaml @@ -0,0 +1,117 @@ +# user-data-service-poa.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-data-service-test + name: user-data-service-poa-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + SERVER_TOMCAT_ACCEPT_COUNT: "5000" + SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + SERVER_TOMCAT_MAX_THREADS: "800" + SERVER_TOMCAT_MIN_SPARE_THREADS: "100" + + + SPRING_DATASOURCE_DRUID_INITIAL_SIZE: "10" + SPRING_DATASOURCE_DRUID_MAX_ACTIVE: "50" + SPRING_DATASOURCE_DRUID_MIN_IDLE: "10" + + + CASSERVER_SA_API_SERVER_URL: http://cas-server-sa-api-svc.cas-server-test.svc.cluster.local:8080 + CASSERVER_SA_API_CLIENT_AUTH_ENABLED: "false" + #CASSERVER_SA_API_CLIENT_AUTH_KEY_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + TPAS_FILE_API_URL: http://agent-service-svc.thirdparty-agent-service-test.svc.cluster.local:8080/api/v1/tpas/file/db + TPAS_CLIENT_AUTH_ENABLED: "false" + #TPAS_CLIENT_AUTH_KEY_PASSWORD: "" + #TPAS_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #TPAS_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #TPAS_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #TPAS_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: user-data-service-test + name: user-data-service-poa-svc + labels: + app: user-data-service-poa + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: user-data-service-poa + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: user-data-service-test + name: user-data-service-poa +spec: + selector: + matchLabels: + app: user-data-service-poa + replicas: 1 + template: + metadata: + labels: + app: user-data-service-poa + spec: + containers: + - name: user-data-service-poa + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/goa/poa-api:0.1.1-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: user-data-service-poa-env + resources: + requests: + memory: "512Mi" + limits: + memory: "512Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.2.user-data-service-goa.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.2.user-data-service-goa.yaml new file mode 100644 index 0000000..515ddde --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.2.user-data-service-goa.yaml @@ -0,0 +1,137 @@ +# user-data-service-goa.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-data-service-test + name: user-data-service-goa-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + + SERVER_TOMCAT_ACCEPT_COUNT: "5000" + SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + SERVER_TOMCAT_MAX_THREADS: "800" + SERVER_TOMCAT_MIN_SPARE_THREADS: "100" + + SPRING_DATASOURCE_DRUID_INITIAL_SIZE: "10" + SPRING_DATASOURCE_DRUID_MAX_ACTIVE: "20" + SPRING_DATASOURCE_DRUID_MIN_IDLE: "10" + + SPRING_REDIS_JEDIS_POOL_MAXACTIVE: "800" + SPRING_REDIS_JEDIS_POOL_MAXIDLE: "100" + SPRING_REDIS_JEDIS_POOL_MINIDLE: "100" + + + # 加密算法的实现,默认 default,支持 bcrypt 等加密算法; SHA-256 支持 SHA-256 加密算法 + PASSWORD_ENCODER_IMPL: default + + SECURITY_API_SECURITY_ACCOUNT_SERVICE_IMPL: redis + + + # 推送数据到 jobs-server 的配置 + JOBS_RABBITMQ_ENABLED: "false" + JOBS_RABBITMQ_HOST: rabbitmq-server.jobs-server-test.svc.cluster.local + JOBS_RABBITMQ_PORT: "5672" + JOBS_RABBITMQ_USERNAME: guest + JOBS_RABBITMQ_PASSWORD: guest + + + # 是否同步帐号到 openldap(已弃用) + # JOBS_RABBITMQ_ACCOUNTUSERSVC2OPENLDAPRABBITSENDER_ENABLED: "false" + + # 是否同步帐号数据至 jobs 的 MQ,由 jobs 再进行分发(如分发到 openldap) + JOBS_RABBITMQ_ACCOUNTUSERSVC2JOBSRABBITSENDER_ENABLED: "false" + # 是否同步密码(明文密码)到 jobs 的 MQ,由 jobs 再进行分发(如分发到 城市热点) + JOBS_RABBITMQ_ACCOUNTUSERSVC2JOBSSYNCPASSWORDRABBITSENDER_ENABLED: "false" + + # 是否同步组织机构数据至 jobs 的 MQ,由 jobs 再进行分发(如分发到 openldap) + JOBS_RABBITMQ_ORGANIZATIONUSERSVC2JOBSRABBITSENDER_ENABLED: "false" + + # 是否同步用户组数据至 jobs 的 MQ,由 jobs 再进行分发(如分发到 openldap) + JOBS_RABBITMQ_GROUPUSERSVC2JOBSRABBITSENDER_ENABLED: "false" + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: user-data-service-test + name: user-data-service-goa-svc + labels: + app: user-data-service-goa + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: user-data-service-goa + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: user-data-service-test + name: user-data-service-goa +spec: + selector: + matchLabels: + app: user-data-service-goa + replicas: 1 + template: + metadata: + labels: + app: user-data-service-goa + spec: + containers: + - name: user-data-service-goa + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/goa/goa-api:0.1.1-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - secretRef: + name: redis-env-secret + - secretRef: + name: rabbitmq-env-secret + - configMapRef: + name: user-data-service-goa-env + resources: + requests: + memory: "1024Mi" + limits: + memory: "1024Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.3.user-data-service-biz.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.3.user-data-service-biz.yaml new file mode 100644 index 0000000..46ade42 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/4.3.user-data-service-biz.yaml @@ -0,0 +1,112 @@ +# user-data-service-biz.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-data-service-test + name: user-data-service-biz-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + + SPRING_DATASOURCE_DRUID_INITIAL_SIZE: "10" + SPRING_DATASOURCE_DRUID_MAX_ACTIVE: "20" + SPRING_DATASOURCE_DRUID_MIN_IDLE: "10" + + + CASSERVER_SA_API_SERVER_URL: http://cas-server-sa-api-svc.cas-server-test.svc.cluster.local:8080 + CASSERVER_SA_API_CLIENT_AUTH_ENABLED: "false" + #CASSERVER_SA_API_CLIENT_AUTH_KEY_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + TPAS_FILE_API_URL: http://agent-service-svc.thirdparty-agent-service-test.svc.cluster.local:8080/api/v1/tpas/file/db + TPAS_CLIENT_AUTH_ENABLED: "false" + #TPAS_CLIENT_AUTH_KEY_PASSWORD: "" + #TPAS_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #TPAS_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #TPAS_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #TPAS_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: user-data-service-test + name: user-data-service-biz-svc + labels: + app: user-data-service-biz + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: user-data-service-biz + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: user-data-service-test + name: user-data-service-biz +spec: + selector: + matchLabels: + app: user-data-service-biz + replicas: 1 + template: + metadata: + labels: + app: user-data-service-biz + spec: + containers: + - name: user-data-service-biz + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/goa/biz-api:0.1.1-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: user-data-service-biz-env + resources: + requests: + memory: "512Mi" + limits: + memory: "512Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/5.user-data-service-datax-job.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/5.user-data-service-datax-job.yaml new file mode 100644 index 0000000..1a94845 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/2.user-data-service/5.user-data-service-datax-job.yaml @@ -0,0 +1,56 @@ +# user-data-service-datax-job.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-data-service-test + name: user-data-service-datax-job-env +data: + JOB_APPLICATION_AUTHZ2USER_MYSQLREADER8_USERNAME: "user_authz" + # 修改为实际的数据库密码 + JOB_APPLICATION_AUTHZ2USER_MYSQLREADER8_PASSWORD: "Nwpu@Supwisdom123" + JOB_APPLICATION_AUTHZ2USER_MYSQLREADER8_JDBC_URL: "jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user_authz?serverTimezone=Asia/Shanghai" + + JOB_APPLICATION_AUTHZ2USER_MYSQLWRITER8_USERNAME: "user" + # 修改为实际的数据库密码 + JOB_APPLICATION_AUTHZ2USER_MYSQLWRITER8_PASSWORD: "Nwpu@Supwisdom123" + JOB_APPLICATION_AUTHZ2USER_MYSQLWRITER8_JDBC_URL: "jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user?serverTimezone=Asia/Shanghai" + +--- +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + namespace: user-data-service-test + name: user-data-service-datax-job +spec: + schedule: "*/10 * * * *" + jobTemplate: + metadata: + labels: + app: user-data-service-datax-job + spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: user-data-service-datax-job + spec: + restartPolicy: Never + containers: + - name: user-data-service-datax-job + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/goa/datax-job:0.1.1-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: user-data-service-datax-job-env + # resources: + # requests: + # memory: "400Mi" + # limits: + # memory: "400Mi" + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/0.user-authorization-service-base.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/0.user-authorization-service-base.yaml new file mode 100644 index 0000000..6e1d29b --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/0.user-authorization-service-base.yaml @@ -0,0 +1,17 @@ +# user-authorization-service-base.yaml + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: user-authorization-service-test + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/1.user-authorization-service-env.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/1.user-authorization-service-env.yaml new file mode 100644 index 0000000..18669c0 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/1.user-authorization-service-env.yaml @@ -0,0 +1,26 @@ +# user-authorization-service-env.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-authorization-service-test + name: jvm-env +data: + MAX_RAM_PERCENTAGE: "75.0" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: user-authorization-service-test + name: datasource-env-secret +type: Opaque +data: + # jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user_authz?serverTimezone=Asia/Shanghai + JDBC_URL: amRiYzpteXNxbDovL215c3FsLXNlcnZlci5hdXRoeC1zZXJ2aWNlLXRlc3Quc3ZjLmNsdXN0ZXIubG9jYWw6MzMwNi91c2VyX2F1dGh6P3NlcnZlclRpbWV6b25lPUFzaWEvU2hhbmdoYWk= + # user_authz + JDBC_USERNAME: dXNlcl9hdXRoeg== + # 修改为实际的数据库密码,并使用 base64 工具进行编码 + # Nwpu@Supwisdom123 + JDBC_PASSWORD: TndwdUBTdXB3aXNkb20xMjM= diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/2.user-authorization-service-ingresses.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/2.user-authorization-service-ingresses.yaml new file mode 100644 index 0000000..93fa95b --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/2.user-authorization-service-ingresses.yaml @@ -0,0 +1,27 @@ +# user-authorization-service-ingresses.yaml + +# 创建 ca-secret + +# cd PATH/ca/certs/client + +# kubectl describe secret ca-secret -n user-authorization-service + +# kubectl create secret generic ca-secret --from-file=client.truststore=client.truststore -n user-authorization-service + +# 暂时不使用,直接使用内部地址 +# --- +# apiVersion: extensions/v1beta1 +# kind: Ingress +# metadata: +# namespace: user-authorization-service-test +# name: user-authz-api-ingress +# spec: +# rules: +# # 修改为学校的根域名 +# - host: user-authz-api.paas.xxx.edu.cn +# http: +# paths: +# - path: / +# backend: +# serviceName: user-authorization-poa-svc +# servicePort: http diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.0.user-authorization-installer.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.0.user-authorization-installer.yaml new file mode 100644 index 0000000..c88d74b --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.0.user-authorization-installer.yaml @@ -0,0 +1,47 @@ +# user-authorization-installer.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-authorization-service-test + name: user-authorization-installer-env +data: + DB_TYPE: mysql8 + + +--- +apiVersion: batch/v1 +kind: Job +metadata: + namespace: user-authorization-service-test + name: user-authorization-installer +spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: user-authorization-installer + spec: + restartPolicy: Never + containers: + - name: user-authorization-installer + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/user-authorization-service/user-authorization-installer:1.0.1-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: user-authorization-installer-env + resources: + requests: + memory: "256Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.1.user-authorization-poa.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.1.user-authorization-poa.yaml new file mode 100644 index 0000000..5d55242 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.1.user-authorization-poa.yaml @@ -0,0 +1,110 @@ +# user-authorization-poa.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-authorization-service-test + name: user-authorization-poa-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + SERVER_TOMCAT_ACCEPT_COUNT: "5000" + SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + SERVER_TOMCAT_MAX_THREADS: "800" + SERVER_TOMCAT_MIN_SPARE_THREADS: "100" + + + SPRING_DATASOURCE_DRUID_INITIAL_SIZE: "10" + SPRING_DATASOURCE_DRUID_MAX_ACTIVE: "50" + SPRING_DATASOURCE_DRUID_MIN_IDLE: "10" + + + USER_DATA_SERVICE_SERVER_URL: http://user-data-service-goa-svc.user-data-service-test.svc.cluster.local:8080 + USER_DATA_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_DATA_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: user-authorization-service-test + name: user-authorization-poa-svc + labels: + app: user-authorization-poa + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: user-authorization-poa + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: user-authorization-service-test + name: user-authorization-poa +spec: + selector: + matchLabels: + app: user-authorization-poa + replicas: 1 + template: + metadata: + labels: + app: user-authorization-poa + spec: + containers: + - name: user-authorization-poa + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/user-authorization-service/user-authorization-poa:1.0.1-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - secretRef: + name: datasource-env-secret + - configMapRef: + name: jvm-env + - configMapRef: + name: user-authorization-poa-env + resources: + requests: + memory: "512Mi" + limits: + memory: "512Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.2.user-authorization-sa.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.2.user-authorization-sa.yaml new file mode 100644 index 0000000..54cd1fd --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/4.2.user-authorization-sa.yaml @@ -0,0 +1,106 @@ +# user-authorization-sa.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-authorization-service-test + name: user-authorization-sa-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + SERVER_TOMCAT_ACCEPT_COUNT: "5000" + SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + SERVER_TOMCAT_MAX_THREADS: "800" + SERVER_TOMCAT_MIN_SPARE_THREADS: "100" + + + SPRING_DATASOURCE_DRUID_INITIAL_SIZE: "10" + SPRING_DATASOURCE_DRUID_MAX_ACTIVE: "20" + SPRING_DATASOURCE_DRUID_MIN_IDLE: "10" + + + # SBA_URL: http://spring-boot-admin-svc.base.svc.cluster.local:8080 + + # LOGGING_LEVEL_COM_SUPWISDOM_INSTITUTE_USER_AUTHORIZATION_SERVICE_SA_MANGRANTED: debug + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: user-authorization-service-test + name: user-authorization-sa-svc + labels: + app: user-authorization-sa + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: user-authorization-sa + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: user-authorization-service-test + name: user-authorization-sa +spec: + selector: + matchLabels: + app: user-authorization-sa + replicas: 1 + template: + metadata: + labels: + app: user-authorization-sa + spec: + containers: + - name: user-authorization-sa + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/user-authorization-service/user-authorization-sa:1.0.1-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - secretRef: + name: datasource-env-secret + - configMapRef: + name: jvm-env + - configMapRef: + name: user-authorization-sa-env + resources: + requests: + memory: "1024Mi" + limits: + memory: "1024Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8888 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/5.user-authorization-datax-job.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/5.user-authorization-datax-job.yaml new file mode 100644 index 0000000..a8e0f95 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/3.user-authorization-service/5.user-authorization-datax-job.yaml @@ -0,0 +1,57 @@ +# user-authorization-datax-job.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: user-authorization-service-test + name: user-authorization-datax-job-env +data: + JOB_USER2AUTHZ_MYSQLREADER8_USERNAME: "user" + # 修改为实际的数据库密码 + JOB_USER2AUTHZ_MYSQLREADER8_PASSWORD: "kingstar" + JOB_USER2AUTHZ_MYSQLREADER8_JDBC_URL: "jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user?serverTimezone=Asia/Shanghai" + + JOB_USER2AUTHZ_MYSQLWRITER8_USERNAME: "user_authz" + # 修改为实际的数据库密码 + JOB_USER2AUTHZ_MYSQLWRITER8_PASSWORD: "kingstar" + JOB_USER2AUTHZ_MYSQLWRITER8_JDBC_URL: "jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user_authz?serverTimezone=Asia/Shanghai" + + +--- +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + namespace: user-authorization-service-test + name: user-authorization-datax-job +spec: + schedule: "*/10 * * * *" + jobTemplate: + metadata: + labels: + app: user-authorization-datax-job + spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: user-authorization-datax-job + spec: + restartPolicy: Never + containers: + - name: user-authorization-datax-job + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/user-authorization-service/user-authorization-datax-job:1.0.1-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: user-authorization-datax-job-env + # resources: + # requests: + # memory: "400Mi" + # limits: + # memory: "400Mi" + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/0.cas-server-base.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/0.cas-server-base.yaml new file mode 100644 index 0000000..673353c --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/0.cas-server-base.yaml @@ -0,0 +1,215 @@ +# cas-server-base.yaml + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: cas-server-test + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 + + +#################################################### +# redis-server +#################################################### +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: cas-server-test + name: redis-server + labels: + app: redis + release: redis-server +type: Opaque +data: + REDIS_PASSWORD: OEt1d29zbE9pdXc3SA== + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: cas-server-test + name: redis-server + labels: + app: redis + release: redis-server +spec: + ports: + - name: redis + port: 6379 + protocol: TCP + targetPort: redis + selector: + app: redis + release: redis-server + role: master + type: ClusterIP +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: cas-server-test + name: redis-server + labels: + app: redis + release: redis-server +spec: + podManagementPolicy: OrderedReady + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: redis + release: redis-server + role: master + serviceName: redis-master + template: + metadata: + labels: + app: redis + release: redis-server + role: master + spec: + containers: + - name: redis-server + env: + - name: REDIS_DISABLE_COMMANDS + value: FLUSHDB,FLUSHALL + - name: REDIS_REPLICATION_MODE + value: master + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-server + key: REDIS_PASSWORD + # 若使用了学校搭设的私有仓库,请修改 + image: bitnami/redis:4.0 + # 若使用了学校搭设的私有仓库,请修改 为 Always + imagePullPolicy: IfNotPresent + # imagePullPolicy: Always + livenessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - containerPort: 6379 + name: redis + protocol: TCP + readinessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 5 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + volumeMounts: + - mountPath: /bitnami/redis/data + name: redis-data + dnsPolicy: ClusterFirst + restartPolicy: Always + securityContext: + fsGroup: 1001 + # runAsUser: 1001 + # https://github.com/bitnami/bitnami-docker-redis/issues/106#issuecomment-388884372 + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - emptyDir: {} + name: redis-data + # 若使用了学校搭设的私有仓库,请增加以下配置(取消注释即可) + # imagePullSecrets: + # - name: harbor-registry + updateStrategy: + rollingUpdate: + partition: 0 + type: RollingUpdate + + +#################################################### +# rabbitmq-server +#################################################### +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: cas-server-test + name: rabbitmq-server + labels: + app: rabbitmq + release: rabbitmq-server +type: Opaque +data: + RABBITMQ_USERNAME: Z3Vlc3Q= + RABBITMQ_PASSWORD: Z3Vlc3Q= + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: cas-server-test + name: rabbitmq-server + labels: + app: rabbitmq-server +spec: + ports: + - port: 5672 + targetPort: tcp-1 + protocol: TCP + name: tcp-1 + - port: 15672 + targetPort: tcp-2 + protocol: TCP + name: tcp-2 + selector: + app: rabbitmq-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: cas-server-test + name: rabbitmq-server +spec: + selector: + matchLabels: + app: rabbitmq-server + replicas: 1 + template: + metadata: + labels: + app: rabbitmq-server + annotations: + sidecar.istio.io/inject: "false" + spec: + containers: + - name: rabbitmq-server + # 若使用了学校搭设的私有仓库,请修改 + image: rabbitmq:management + # 若使用了学校搭设的私有仓库,请修改 为 Always + imagePullPolicy: IfNotPresent + # imagePullPolicy: Always + ports: + - containerPort: 5672 + name: tcp-1 + - containerPort: 15672 + name: tcp-2 + # 若使用了学校搭设的私有仓库,请增加以下配置(取消注释即可) + # imagePullSecrets: + # - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/1.cas-server-env.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/1.cas-server-env.yaml new file mode 100644 index 0000000..39a3199 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/1.cas-server-env.yaml @@ -0,0 +1,51 @@ +# cas-server-env.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: cas-server-test + name: jvm-env +data: + MAX_RAM_PERCENTAGE: "75.0" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: cas-server-test + name: datasource-env-secret +type: Opaque +data: + # jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/cas_server?serverTimezone=Asia/Shanghai + JDBC_URL: amRiYzpteXNxbDovL215c3FsLXNlcnZlci5hdXRoeC1zZXJ2aWNlLXRlc3Quc3ZjLmNsdXN0ZXIubG9jYWw6MzMwNi9jYXNfc2VydmVyP3NlcnZlclRpbWV6b25lPUFzaWEvU2hhbmdoYWk= + # cas_server + JDBC_USERNAME: Y2FzX3NlcnZlcg== + # 修改为实际的数据库密码,并使用 base64 工具进行编码 + # Nwpu@Supwisdom123 + JDBC_PASSWORD: TndwdUBTdXB3aXNkb20xMjM= + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: cas-server-test + name: redis-env-secret +type: Opaque +data: + SPRING_REDIS_HOST: cmVkaXMtc2VydmVy + SPRING_REDIS_PORT: NjM3OQ== + SPRING_REDIS_PASSWORD: OEt1d29zbE9pdXc3SA== + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: cas-server-test + name: rabbitmq-env-secret +type: Opaque +data: + SPRING_RABBITMQ_HOST: cmFiYml0bXEtc2VydmVy + SPRING_RABBITMQ_PORT: NTY3Mg== + SPRING_RABBITMQ_USERNAME: Z3Vlc3Q= + SPRING_RABBITMQ_PASSWORD: Z3Vlc3Q= diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/2.cas-server-ingresses.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/2.cas-server-ingresses.yaml new file mode 100644 index 0000000..a200ce3 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/2.cas-server-ingresses.yaml @@ -0,0 +1,41 @@ +# cas-server-ingresses.yaml + +# 创建 ca-secret + +# cd PATH/ca/certs/client + +# kubectl describe secret ca-secret -n cas-server + +# kubectl create secret generic ca-secret --from-file=client.truststore=client.truststore -n cas-server + + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + namespace: cas-server-test + name: cas-ingress + annotations: + nginx.ingress.kubernetes.io/proxy-buffer-size: "8k" + # cert-manager.io/cluster-issuer: "letsencrypt-staging" + # nginx.ingress.kubernetes.io/ssl-redirect: "true" + # nginx.ingress.kubernetes.io/auth-tls-verify-client: "on" + # nginx.ingress.kubernetes.io/auth-tls-secret: "cas-server/ca-secret" + # nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1" +spec: + # tls: + # - hosts: + # - cas.paas.xxx.edu.cn + # secretName: cas-ingress-tls + rules: + # 修改为学校的根域名 + - host: cas-test.paas.newcapec.cn + http: + paths: + - path: /cas + backend: + serviceName: cas-server-site-webapp-svc + servicePort: http + + +# TODO: https 配置说明 diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.0.cas-server-installer.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.0.cas-server-installer.yaml new file mode 100644 index 0000000..68a8363 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.0.cas-server-installer.yaml @@ -0,0 +1,47 @@ +# cas-server-installer.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: cas-server-test + name: cas-server-installer-env +data: + DB_TYPE: mysql8 + + +--- +apiVersion: batch/v1 +kind: Job +metadata: + namespace: cas-server-test + name: cas-server-installer +spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: cas-server-installer + spec: + restartPolicy: Never + containers: + - name: cas-server-installer + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/cas-server/cas-server-installer:1.0.0-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: cas-server-installer-env + resources: + requests: + memory: "256Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.2.cas-server-sa-api.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.2.cas-server-sa-api.yaml new file mode 100644 index 0000000..fc90464 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.2.cas-server-sa-api.yaml @@ -0,0 +1,125 @@ +# cas-server-sa-api.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: cas-server-test + name: cas-server-sa-api-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + + # SERVER_TOMCAT_ACCEPT_COUNT: "100" + # SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + # SERVER_TOMCAT_MAX_THREADS: "200" + # SERVER_TOMCAT_MIN_SPARE_THREADS: "10" + + SERVICE_REFRESH_REDIS_TIMER_ENABLED: "true" + ACCOUNT_REFRESH_REDIS_TIMER_ENABLED: "false" + FEDERATION_REFRESH_REDIS_TIMER_ENABLED: "true" + + + USER_DATA_SERVICE_SA_API_SERVER_URL: http://user-data-service-goa-svc.user-data-service-test.svc.cluster.local:8080 + USER_DATA_SERVICE_SA_API_CLIENT_AUTH_ENABLED: "false" + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: cas-server-test + name: cas-server-sa-api-env-secret +type: Opaque +data: + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_KEY_PASSWORD: Y2xpZW50 + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: Y2xpZW50 + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: Y2xpZW50 + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: cas-server-test + name: cas-server-sa-api-svc + labels: + app: cas-server-sa-api + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: cas-server-sa-api +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: cas-server-test + name: cas-server-sa-api +spec: + selector: + matchLabels: + app: cas-server-sa-api + replicas: 1 + template: + metadata: + labels: + app: cas-server-sa-api + spec: + containers: + - name: cas-server-sa-api + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/cas-server/cas-server-sa-api:1.0.0-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - secretRef: + name: redis-env-secret + - secretRef: + name: rabbitmq-env-secret + - configMapRef: + name: cas-server-sa-api-env + - secretRef: + name: cas-server-sa-api-env-secret + resources: + requests: + memory: "512Mi" + limits: + memory: "512Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.3.cas-server-security-engine.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.3.cas-server-security-engine.yaml new file mode 100644 index 0000000..bf0ba41 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.3.cas-server-security-engine.yaml @@ -0,0 +1,88 @@ +# cas-server-security-engine.yaml + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: cas-server-test + name: cas-server-security-engine-env-secret +type: Opaque +data: + #CASSERVER_SA_API_CLIENT_AUTH_KEY_PASSWORD: Y2xpZW50 + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: Y2xpZW50 + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: Y2xpZW50 + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: cas-server-test + name: cas-server-security-engine-env +data: + CASSERVER_SA_API_SERVER_URL: http://cas-server-sa-api-svc.cas-server-test.svc.cluster.local:8080 + CASSERVER_SA_API_CLIENT_AUTH_ENABLED: "false" + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: cas-server-test + name: cas-server-security-engine-svc + labels: + app: cas-server-security-engine + needMonitor: 'true' +spec: + ports: + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: cas-server-security-engine + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: cas-server-test + name: cas-server-security-engine +spec: + selector: + matchLabels: + app: cas-server-security-engine + replicas: 1 + template: + metadata: + labels: + app: cas-server-security-engine + spec: + containers: + - name: cas-server-security-engine + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/cas-server/cas-server-security-engine:1.0.0-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - secretRef: + name: rabbitmq-env-secret + - configMapRef: + name: cas-server-security-engine-env + - secretRef: + name: cas-server-security-engine-env-secret + resources: + requests: + memory: "400Mi" + limits: + memory: "400Mi" + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.5.cas-server-site-webapp.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.5.cas-server-site-webapp.yaml new file mode 100644 index 0000000..6a782d3 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/4.5.cas-server-site-webapp.yaml @@ -0,0 +1,235 @@ +# cas-server-site-webapp.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: cas-server-test + name: cas-server-site-webapp-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEY_PASSWORD: "" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + SERVER_TOMCAT_ACCEPT_COUNT: "5000" + SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + SERVER_TOMCAT_MAX_THREADS: "800" + SERVER_TOMCAT_MIN_SPARE_THREADS: "100" + + SPRING_REDIS_JEDIS_POOL_MAXACTIVE: "800" + SPRING_REDIS_JEDIS_POOL_MAXIDLE: "100" + SPRING_REDIS_JEDIS_POOL_MINIDLE: "100" + + + LOGGING_CONFIG: file:/etc/cas/log4j2-file.xml + + + ## + # 认证服务的外网访问地址, + # **修改** 学校的根域名 + CAS_SERVER_NAME: https://cas-test.paas.newcapec.cn + + # Ticket Granting Cookie + CAS_TGC_SECURE: "true" + + # TGT Expiration Policy + CAS_TICKET_TGT_MAX_TIME_TO_LIVE_IN_SECONDS: "1209600" + CAS_TICKET_TGT_TIME_TO_KILL_IN_SECONDS: "172800" + + # JWT Tickets + CAS_AUTHN_TOKEN_CRYPTO_SIGNING_KEY: "(@K7qy)awCjxp$L653Mf$2" + + ## + # 登录UI,主题 + SPRING_THYMELEAF_PREFIX: classpath:/templates/themes/classic/ + + ## + # 测试环境中可使用,正式环境下请配置为空 + # + CAS_AUTHN_ACCEPT_USERS: "" + + + ## 配置第三方认证的相关参数 + CASSERVER_FEDERATION_QQ_ENABLED: "true" + CASSERVER_FEDERATION_QQ_NAME: QQ + CASSERVER_FEDERATION_QQ_APPID: "" + CASSERVER_FEDERATION_QQ_APPKEY: "" + + CASSERVER_FEDERATION_OPENWEIXIN_ENABLED: "true" + CASSERVER_FEDERATION_OPENWEIXIN_NAME: 微信 + CASSERVER_FEDERATION_OPENWEIXIN_APPID: "" + CASSERVER_FEDERATION_OPENWEIXIN_APPSECRET: "" + + CASSERVER_FEDERATION_WORKWEIXIN_ENABLED: "true" + CASSERVER_FEDERATION_WORKWEIXIN_NAME: 企业微信 + CASSERVER_FEDERATION_WORKWEIXIN_CORPID: "" + CASSERVER_FEDERATION_WORKWEIXIN_AGENTID: "" + CASSERVER_FEDERATION_WORKWEIXIN_SECRET: "" + + CASSERVER_FEDERATION_ALIPAY_ENABLED: "true" + CASSERVER_FEDERATION_ALIPAY_NAME: 支付宝 + CASSERVER_FEDERATION_ALIPAY_APPID: "" + CASSERVER_FEDERATION_ALIPAY_APPPRIVATEKEY: "" + CASSERVER_FEDERATION_ALIPAY_ALIPAYPUBLICKEY: "" + + + # **修改** + # jwt 的签发方标识,一般为 认证的域名 + CASSERVER_JWT_ISS: cas-test.paas.newcapec.cn + # **修改** + # 参考 certs/jwt/readme.md 生成公私钥pem,修改相关配置 + CASSERVER_JWT_PRIVATE_KEY_PEM_PKCS8: "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDKivcJfoDpTgShIdrC0AuImgHQKQmdv/CZWRxVPkSY26kZWtVJ4mjzRkDGyB31LUJlVfFNe0nteOyqfNHrhC+uf612+P0KTmT/pOenoegpT8BDEDe1DlmrDoPqKE87JVXjPhx0rnCPMQE0+Em5OOPM/hVDiHhWx5Y1t+FcYre9J6zyg2flbCiv2vVRsQk/9kwesMnEBzB7QY+95sCoSng7llxO1aer7+qShQHrP/nYScIyW2g+a4wL6jd9Z0gIF/irvShIMKV+6EtWLiZFPYrlRQfx+zER7qg+2S+T29UII5lGajQxeldmIip1k62BwHOf/SbOg13nwrF4jLSCKeN/AgMBAAECggEAVtWHHcHngJ6bK325LSZGm5TzTAwb/E6q1wO2OvGMNUCPWbhwktGHjyzCXray6UczHQDgiAhgZHggduM2mFM+ogBJHSWYTo/XiyZmzp6CSxvO4LGWQIBbfxOlCIGpnkDedqNNTdTvmuQ2kUAVU1yJhXw1H5Pli8bbpkIkUxhbj7MsmcSZS4Xaqj1jhOWoBzt1SZEpHgDZ4m8MEMBfjLu+/SQAIWGdJmyANdsU3V/f/DmcgSqu7oTFYZiEFyJqTRyCVHJmyIqAOAtqHkKnJcGfeurwUIuX5NVqdYhj/JM+3k8lXDRyoyC0QADhnfR85uXV/OnXCVBC8GABuMP4DaiHyQKBgQDjwjtbVb/jQur2JYsSDS0sZI3S4X929gWU66AyClnUNbRIVcN4Lyhnp8+d/m9+oVV6kDfjTDnuEz7TWHr94RFcecdivehzxRHdRlRp+IhmtCtzstPhS5f0U6/e59CryxgxV+h5jDUssokzdz1bLsnC8+VgKNL2jVXqkuLkF3RqhQKBgQDjqE186VX3oej5YlmLmqi4LVFFVzpX75dOjAFc+ke/SPXm11o7lj1ONr+t9ZKcwvPx9j5OPXJajbaE2Qx1KXzTPKQT44GdpOvistOJQSNpx2e00K4Sn/7bsJq++UJ7FtmR+iJvfYq1uW1z5taVIjh5hhwFtIBW38voNcghCXVvMwKBgAUwRpPlFzMBMkMbRdjKbg4F2GlGc9Xs8uGaoJKjQ7qe4pWHRqW1RVFfNE6gHkAfQshBAtTtxqAS1iqQaHTiLLgTmiQ4uVPx2F9XG9MyM0FLt3WyTDtksniBc487briLLujo3MXwGMIE6zU98SrjnPsQ/Ve8dlnhjGSEpiCWHDPVAoGAZwNmJMqUytvpxsbZDBGsnMJszvqcfOP+TF2P1FmwE39ZPd5ehy4BiZ2+eGHxuJuCtQ8evFqTnyQW3eA1AeMHB7Kd8B33LbVNw6P1klr2QkwnwirXSbg6I4CzVQ0HJxl809Aiut5M4NQKEfL3UD5O3bZwgahelnDoHKgRadmU2P8CgYANBbxpDT1SdyJUFuKzJ5/cUPBFzOn3eNGRo/RejXSCi5Spd9OoTwDh6dbffk7pUWLYH/BFILW9+RL8uhMt8mdTWVgDKrNrdZLdWUBNsb89St9x/JwlucqgbTvzf0G0h/ZiGNzyPhgGABRrlWVYIdS8KLdTYUkvPHsEAtxR+kwTAg==" + CASSERVER_JWT_PUBLIC_KEY_PEM: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyor3CX6A6U4EoSHawtALiJoB0CkJnb/wmVkcVT5EmNupGVrVSeJo80ZAxsgd9S1CZVXxTXtJ7XjsqnzR64Qvrn+tdvj9Ck5k/6Tnp6HoKU/AQxA3tQ5Zqw6D6ihPOyVV4z4cdK5wjzEBNPhJuTjjzP4VQ4h4VseWNbfhXGK3vSes8oNn5Wwor9r1UbEJP/ZMHrDJxAcwe0GPvebAqEp4O5ZcTtWnq+/qkoUB6z/52EnCMltoPmuMC+o3fWdICBf4q70oSDClfuhLVi4mRT2K5UUH8fsxEe6oPtkvk9vVCCOZRmo0MXpXZiIqdZOtgcBzn/0mzoNd58KxeIy0ginjfwIDAQAB" + + # **视情况修改** + ## 是否启用登录验证码 + CASSERVERSITE_CAPTCHA_ENABLED: "false" + + ## 配置用户的登录名的正则校验(用于手机、邮箱登录的判断) + #CASSERVERSITE_USERNAME_REGEX_MOBILE: "" + # \d{11}$ + #CASSERVERSITE_USERNAME_REGEX_EMAIL_ADDRESS: "" + # \w+\.?\w+@\w+\.[a-z]+(\.[a-z]+)? + + ## 配置认证时,帐号服务的实现( redis 帐号数据存放在redis中, user-sa 帐号数据从用户服务获取) + CASSERVERSITE_ACCOUNT_SERVICE_IMPL: user-sa + + ## 配置认证时,角色服务的实现( redis 角色数据存放在redis中, user-authz-sa 角色数据从授权服务获取) + CASSERVERSITE_ROLE_SERVICE_IMPL: user-authz-sa + + ## 配置认证时,动态码的短信发送实现( default 控制台输出, agent-service 代理服务) + CASSERVERSITE_SMS_SENDER_IMPL: agent-service + + # **修改** 学校的根域名 + CASSERVERSITE_FORGOT_PASSWORD_URL: https://security-center-test.paas.newcapec.cn/find-pwd + CASSERVERSITE_ACTIVE_ACCOUNT_URL: https://security-center-test.paas.newcapec.cn/active-account + + ## 动态码登录相关配置 + CASSERVERSITE_PASSWORDLESS_TOKEN_EXPIRATION_IN_SECONDS: "300" + CASSERVERSITE_PASSWORDLESS_SMS_FROM: 认证中心 + # **修改** 根据实际情况,修改短信模板 + CASSERVERSITE_PASSWORDLESS_SMS_TEXT_TEMPLATE: 【认证中心】{name}:您正在登录统一身份认证,本次登录的动态密码为{token},有效期5分钟,请尽快完成登录。 + + + TPAS_AGENT_SERVICE_SERVER_URL: http://agent-service-svc.thirdparty-agent-service-test.svc.cluster.local:8080 + TPAS_AGENT_SERVICE_CLIENT_AUTH_ENABLED: "false" + #TPAS_AGENT_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #TPAS_AGENT_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #TPAS_AGENT_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #TPAS_AGENT_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #TPAS_AGENT_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + # **修改** + # 若须对接sms 接口,须进行二开定制 + TPAS_AGENT_SERVICE_SMS_SENDER_PATH: /api/v1/tpas/sms/console/send + + + CASSERVER_SA_API_SERVER_URL: http://cas-server-sa-api-svc.cas-server-test.svc.cluster.local:8080 + CASSERVER_SA_API_CLIENT_AUTH_ENABLED: "false" + #CASSERVER_SA_API_CLIENT_AUTH_KEY_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + + USER_DATA_SERVICE_SA_API_SERVER_URL: http://user-data-service-goa-svc.user-data-service-test.svc.cluster.local:8080 + USER_DATA_SERVICE_SA_API_CLIENT_AUTH_ENABLED: "false" + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + + USER_AUTHZ_SERVICE_SA_API_SERVER_URL: http://user-authorization-sa-svc.user-authorization-service-test.svc.cluster.local:8080 + USER_AUTHZ_SERVICE_SA_API_CLIENT_AUTH_ENABLED: "false" + #USER_AUTHZ_SERVICE_SA_API_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_AUTHZ_SERVICE_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #USER_AUTHZ_SERVICE_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_AUTHZ_SERVICE_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #USER_AUTHZ_SERVICE_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + ## + # 超级APP Token 的验签公钥 + # 如须和 超级APP 进行对接,修改此配置 + # **修改** 学校的根域名 + SUPERAPP_TOKEN_SIGNING_KEY_URL: https://token-test.paas.newcapec.cn/jwt/publicKey + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: cas-server-test + name: cas-server-site-webapp-svc + labels: + app: cas-server-site-webapp + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: cas-server-site-webapp +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: cas-server-test + name: cas-server-site-webapp +spec: + selector: + matchLabels: + app: cas-server-site-webapp + replicas: 1 + template: + metadata: + labels: + app: cas-server-site-webapp + spec: + containers: + - name: cas-server-site-webapp + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/cas-server/cas-server-site-webapp:1.0.0-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: redis-env-secret + - secretRef: + name: rabbitmq-env-secret + - configMapRef: + name: cas-server-site-webapp-env + resources: + requests: + memory: "800Mi" + limits: + memory: "800Mi" + readinessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 30 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/5.cas-server-datax-job.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/5.cas-server-datax-job.yaml new file mode 100644 index 0000000..0c3c254 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/5.cas-server-datax-job.yaml @@ -0,0 +1,57 @@ +# cas-server-datax-job.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: cas-server-test + name: cas-server-datax-job-env +data: + JOB_ACCOUNT_USER2CAS_MYSQLREADER8_USERNAME: "user" + # 修改为实际的数据库密码 + JOB_ACCOUNT_USER2CAS_MYSQLREADER8_PASSWORD: "kingstar" + JOB_ACCOUNT_USER2CAS_MYSQLREADER8_JDBC_URL: "jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user?serverTimezone=Asia/Shanghai" + + JOB_ACCOUNT_USER2CAS_MYSQLWRITER8_USERNAME: "cas_server" + # 修改为实际的数据库密码 + JOB_ACCOUNT_USER2CAS_MYSQLWRITER8_PASSWORD: "kingstar" + JOB_ACCOUNT_USER2CAS_MYSQLWRITER8_JDBC_URL: "jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/cas_server?serverTimezone=Asia/Shanghai" + + +--- +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + namespace: cas-server-test + name: cas-server-datax-job +spec: + schedule: "*/5 * * * *" + jobTemplate: + metadata: + labels: + app: cas-server-datax-job + spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: cas-server-datax-job + spec: + restartPolicy: Never + containers: + - name: cas-server-datax-job + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/cas-server/cas-server-datax-job:1.0.0-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: cas-server-datax-job-env + # resources: + # requests: + # memory: "400Mi" + # limits: + # memory: "400Mi" + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_private_key.pem b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_private_key.pem new file mode 100644 index 0000000..e1c0db0 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_private_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAyor3CX6A6U4EoSHawtALiJoB0CkJnb/wmVkcVT5EmNupGVrV +SeJo80ZAxsgd9S1CZVXxTXtJ7XjsqnzR64Qvrn+tdvj9Ck5k/6Tnp6HoKU/AQxA3 +tQ5Zqw6D6ihPOyVV4z4cdK5wjzEBNPhJuTjjzP4VQ4h4VseWNbfhXGK3vSes8oNn +5Wwor9r1UbEJP/ZMHrDJxAcwe0GPvebAqEp4O5ZcTtWnq+/qkoUB6z/52EnCMlto +PmuMC+o3fWdICBf4q70oSDClfuhLVi4mRT2K5UUH8fsxEe6oPtkvk9vVCCOZRmo0 +MXpXZiIqdZOtgcBzn/0mzoNd58KxeIy0ginjfwIDAQABAoIBAFbVhx3B54Cemyt9 +uS0mRpuU80wMG/xOqtcDtjrxjDVAj1m4cJLRh48swl62sulHMx0A4IgIYGR4IHbj +NphTPqIASR0lmE6P14smZs6egksbzuCxlkCAW38TpQiBqZ5A3najTU3U75rkNpFA +FVNciYV8NR+T5YvG26ZCJFMYW4+zLJnEmUuF2qo9Y4TlqAc7dUmRKR4A2eJvDBDA +X4y7vv0kACFhnSZsgDXbFN1f3/w5nIEqru6ExWGYhBciak0cglRyZsiKgDgLah5C +pyXBn3rq8FCLl+TVanWIY/yTPt5PJVw0cqMgtEAA4Z30fObl1fzp1wlQQvBgAbjD ++A2oh8kCgYEA48I7W1W/40Lq9iWLEg0tLGSN0uF/dvYFlOugMgpZ1DW0SFXDeC8o +Z6fPnf5vfqFVepA340w57hM+01h6/eERXHnHYr3oc8UR3UZUafiIZrQrc7LT4UuX +9FOv3ufQq8sYMVfoeYw1LLKJM3c9Wy7JwvPlYCjS9o1V6pLi5Bd0aoUCgYEA46hN +fOlV96Ho+WJZi5qouC1RRVc6V++XTowBXPpHv0j15tdaO5Y9Tja/rfWSnMLz8fY+ +Tj1yWo22hNkMdSl80zykE+OBnaTr4rLTiUEjacdntNCuEp/+27CavvlCexbZkfoi +b32Ktbltc+bWlSI4eYYcBbSAVt/L6DXIIQl1bzMCgYAFMEaT5RczATJDG0XYym4O +BdhpRnPV7PLhmqCSo0O6nuKVh0altUVRXzROoB5AH0LIQQLU7cagEtYqkGh04iy4 +E5okOLlT8dhfVxvTMjNBS7d1skw7ZLJ4gXOPO264iy7o6NzF8BjCBOs1PfEq45z7 +EP1XvHZZ4YxkhKYglhwz1QKBgGcDZiTKlMrb6cbG2QwRrJzCbM76nHzj/kxdj9RZ +sBN/WT3eXocuAYmdvnhh8bibgrUPHrxak58kFt3gNQHjBweynfAd9y21TcOj9ZJa +9kJMJ8Iq10m4OiOAs1UNBycZfNPQIrreTODUChHy91A+Tt22cIGoXpZw6ByoEWnZ +lNj/AoGADQW8aQ09UnciVBbisyef3FDwRczp93jRkaP0Xo10gouUqXfTqE8A4enW +335O6VFi2B/wRSC1vfkS/LoTLfJnU1lYAyqza3WS3VlATbG/PUrfcfycJbnKoG07 +839BtIf2Yhjc8j4YBgAUa5VlWCHUvCi3U2FJLzx7BALcUfpMEwI= +-----END RSA PRIVATE KEY----- diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_private_key_pkcs8.pem b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_private_key_pkcs8.pem new file mode 100644 index 0000000..4c9e224 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_private_key_pkcs8.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDKivcJfoDpTgSh +IdrC0AuImgHQKQmdv/CZWRxVPkSY26kZWtVJ4mjzRkDGyB31LUJlVfFNe0nteOyq +fNHrhC+uf612+P0KTmT/pOenoegpT8BDEDe1DlmrDoPqKE87JVXjPhx0rnCPMQE0 ++Em5OOPM/hVDiHhWx5Y1t+FcYre9J6zyg2flbCiv2vVRsQk/9kwesMnEBzB7QY+9 +5sCoSng7llxO1aer7+qShQHrP/nYScIyW2g+a4wL6jd9Z0gIF/irvShIMKV+6EtW +LiZFPYrlRQfx+zER7qg+2S+T29UII5lGajQxeldmIip1k62BwHOf/SbOg13nwrF4 +jLSCKeN/AgMBAAECggEAVtWHHcHngJ6bK325LSZGm5TzTAwb/E6q1wO2OvGMNUCP +WbhwktGHjyzCXray6UczHQDgiAhgZHggduM2mFM+ogBJHSWYTo/XiyZmzp6CSxvO +4LGWQIBbfxOlCIGpnkDedqNNTdTvmuQ2kUAVU1yJhXw1H5Pli8bbpkIkUxhbj7Ms +mcSZS4Xaqj1jhOWoBzt1SZEpHgDZ4m8MEMBfjLu+/SQAIWGdJmyANdsU3V/f/Dmc +gSqu7oTFYZiEFyJqTRyCVHJmyIqAOAtqHkKnJcGfeurwUIuX5NVqdYhj/JM+3k8l +XDRyoyC0QADhnfR85uXV/OnXCVBC8GABuMP4DaiHyQKBgQDjwjtbVb/jQur2JYsS +DS0sZI3S4X929gWU66AyClnUNbRIVcN4Lyhnp8+d/m9+oVV6kDfjTDnuEz7TWHr9 +4RFcecdivehzxRHdRlRp+IhmtCtzstPhS5f0U6/e59CryxgxV+h5jDUssokzdz1b +LsnC8+VgKNL2jVXqkuLkF3RqhQKBgQDjqE186VX3oej5YlmLmqi4LVFFVzpX75dO +jAFc+ke/SPXm11o7lj1ONr+t9ZKcwvPx9j5OPXJajbaE2Qx1KXzTPKQT44GdpOvi +stOJQSNpx2e00K4Sn/7bsJq++UJ7FtmR+iJvfYq1uW1z5taVIjh5hhwFtIBW38vo +NcghCXVvMwKBgAUwRpPlFzMBMkMbRdjKbg4F2GlGc9Xs8uGaoJKjQ7qe4pWHRqW1 +RVFfNE6gHkAfQshBAtTtxqAS1iqQaHTiLLgTmiQ4uVPx2F9XG9MyM0FLt3WyTDtk +sniBc487briLLujo3MXwGMIE6zU98SrjnPsQ/Ve8dlnhjGSEpiCWHDPVAoGAZwNm +JMqUytvpxsbZDBGsnMJszvqcfOP+TF2P1FmwE39ZPd5ehy4BiZ2+eGHxuJuCtQ8e +vFqTnyQW3eA1AeMHB7Kd8B33LbVNw6P1klr2QkwnwirXSbg6I4CzVQ0HJxl809Ai +ut5M4NQKEfL3UD5O3bZwgahelnDoHKgRadmU2P8CgYANBbxpDT1SdyJUFuKzJ5/c +UPBFzOn3eNGRo/RejXSCi5Spd9OoTwDh6dbffk7pUWLYH/BFILW9+RL8uhMt8mdT +WVgDKrNrdZLdWUBNsb89St9x/JwlucqgbTvzf0G0h/ZiGNzyPhgGABRrlWVYIdS8 +KLdTYUkvPHsEAtxR+kwTAg== +-----END PRIVATE KEY----- diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_public_key.pem b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_public_key.pem new file mode 100644 index 0000000..7523d69 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/jwt_public_key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyor3CX6A6U4EoSHawtAL +iJoB0CkJnb/wmVkcVT5EmNupGVrVSeJo80ZAxsgd9S1CZVXxTXtJ7XjsqnzR64Qv +rn+tdvj9Ck5k/6Tnp6HoKU/AQxA3tQ5Zqw6D6ihPOyVV4z4cdK5wjzEBNPhJuTjj +zP4VQ4h4VseWNbfhXGK3vSes8oNn5Wwor9r1UbEJP/ZMHrDJxAcwe0GPvebAqEp4 +O5ZcTtWnq+/qkoUB6z/52EnCMltoPmuMC+o3fWdICBf4q70oSDClfuhLVi4mRT2K +5UUH8fsxEe6oPtkvk9vVCCOZRmo0MXpXZiIqdZOtgcBzn/0mzoNd58KxeIy0ginj +fwIDAQAB +-----END PUBLIC KEY----- diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/readme.md b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/readme.md new file mode 100644 index 0000000..81ac267 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/4.cas-server/certs/jwt/readme.md @@ -0,0 +1,98 @@ +# readme.md + + +## 使用 openssl 生成 公私钥 + + +1. 生成私钥 App Private Key + +必须为 RSA2(SHA256) + +```bash +openssl genrsa -out jwt_private_key.pem 2048 +``` + +2. 将私钥转换为 PKCS8 格式 + +```bash +openssl pkcs8 -topk8 -inform PEM -in jwt_private_key.pem -outform PEM -nocrypt -out jwt_private_key_pkcs8.pem +``` + +3. 导出公钥 App Public Key + +```bash +openssl rsa -in jwt_private_key.pem -pubout -out jwt_public_key.pem +``` + +4. 将 jwt_public_key.pem 中的内容,去除换行和空格,转成字符串。 + +处理前: +```language +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwow0APEh9F91vvtAzl7V +FmXRAOGhlo+22KX+rqC3ziGg4+yIk8evAL1T97XEuK1huqcAp+p4PIG2t/Rb3FBD ++vVJGoXKsyLCMUmT4Sy5/TRhb3TM0CHefvMZTSMwcVzKT07DtxyGgFZj9WsUYZWr +BUPcu0vD6s7m5Qe3qFJJWVeRX8NDnVAxySzrz4bI4+1qvtyey/uap3I6txxRxUlI +aMyTsD8pl63u14dD2FHRM6JY3tmdEpBEMWI91qmYbl9HkH/D6Xtumg0Hmzh06bdr +lO3YNscpr6iN2ug6yGNtAh4/ug4P4ZV9nxImcj8l8Pt3jio1O0IIpf4MUCMD+C7P +rQIDAQAB +-----END PUBLIC KEY----- +``` +处理后: +```language +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwow0APEh9F91vvtAzl7VFmXRAOGhlo+22KX+rqC3ziGg4+yIk8evAL1T97XEuK1huqcAp+p4PIG2t/Rb3FBD+vVJGoXKsyLCMUmT4Sy5/TRhb3TM0CHefvMZTSMwcVzKT07DtxyGgFZj9WsUYZWrBUPcu0vD6s7m5Qe3qFJJWVeRX8NDnVAxySzrz4bI4+1qvtyey/uap3I6txxRxUlIaMyTsD8pl63u14dD2FHRM6JY3tmdEpBEMWI91qmYbl9HkH/D6Xtumg0Hmzh06bdrlO3YNscpr6iN2ug6yGNtAh4/ug4P4ZV9nxImcj8l8Pt3jio1O0IIpf4MUCMD+C7PrQIDAQAB +-----END PUBLIC KEY----- +``` + +4. 将 jwt_private_key_pkcs8.pem 中的内容,去除换行和空格,转成字符串。 + +处理前: +```language +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDCjDQA8SH0X3W+ ++0DOXtUWZdEA4aGWj7bYpf6uoLfOIaDj7IiTx68AvVP3tcS4rWG6pwCn6ng8gba3 +9FvcUEP69UkahcqzIsIxSZPhLLn9NGFvdMzQId5+8xlNIzBxXMpPTsO3HIaAVmP1 +axRhlasFQ9y7S8PqzublB7eoUklZV5Ffw0OdUDHJLOvPhsjj7Wq+3J7L+5qncjq3 +HFHFSUhozJOwPymXre7Xh0PYUdEzolje2Z0SkEQxYj3WqZhuX0eQf8Ppe26aDQeb +OHTpt2uU7dg2xymvqI3a6DrIY20CHj+6Dg/hlX2fEiZyPyXw+3eOKjU7Qgil/gxQ +IwP4Ls+tAgMBAAECggEAaQOlTpza5z5gIKcfZEZsX5q2JvOkddE9sdRolXrLvMkK +P/39+0def9ey65OCjO2KQ2bCQ+Gc5YxfRQzySQpKp7yfqWFu+SNaD6DX4kRyYOtV +bQRvSin+ICi5D5pfG9IqooSxwLX1JHF9o4wZhFN17XGkRLWxG55zpE12JbXFQiPB +pck6hcMfx+r5wk7t4ret/8P/MDcyrPuUavJemd4D2jRrD7AmOGJDvElioFcOKA+V +S8oe/uBdpU8cbYJvct68fHOzG9IW3hdqYV18fhNtWqp9WeuUP+F2UMmOXbAtZ106 +Zcd+V/jsse2G9KvGzmDA61ZGxzHUjt+JNIpN+V2HQQKBgQDkfYb8vIMc2yV0CM30 +mAaPIapgpw8brYS8v+azQR/jjsuHFJ1CQJAih79y2gwdjKbDl0XByjj/qiHLTPcu +6dkuavdsV9MrlFfVqAXUMNDHrWEn5nMahlq3UZbflBqlavTr0gvEA8Da+ZXcRvWg +TP5+g5RFrKHJVOyQ+GzgDggQawKBgQDZ+IDRthf0UHvvZsoUbeb37Wut9jdjRgLJ +S1X4RtH+NPN23lvtTKJmUNfrFxiOfeVBfCXmGep0ibTqDVo0zBeHSu4BFM3BsICu +7xafmLafZxZqHcgWuF9keOCWjKN5fzub5xGqd2yge9hGN2zA2U9qp4mltGzeoZ/0 +TuLuR59GRwKBgCGga7ZUVANyKQ/rn8vod8am0LlKvMl4/vj8UQp+gh/uSvvFR+OR +NuUuDznq5y+OHJjacXS0uzC9LB4MZLBtz/2p1mIGhth6C3cxNDJnQMKyPIMvwi7c +KQujoU2kMUu48vSlw/+EAeT4KFrzwoBl9GpQGQkr/99udSZcuUE8L2mjAoGAPRLn +LVuDTL58a3D2sFC3BcLth/nUPSmxwCsutHlLf5ngme7l/RCa9GY0ibeX9t0JrpaV +m+qpCexH18jT/LUu5oa1N3JX0Kye8eUmBqPoj7N30VX06YDRobpI24Yei/19e0p8 +ZbI+qpzo1YvUGhkJqo21AMwUMTFCO1cbOL6yvyMCgYAHUNBLhSOaIZpvbmyh5uz5 +Va/IIYU5nJcVAan8ExzdVBqeiDqlIDsUt/4xoV2sWOK1lDmL1QYeOOTOHdVcSUyN +ZpvB3b/9RZ1bNQZA1trBBxjY7dXNwZZp0ah/bmO+i4dPXl+bU2mUqdyb1emFwcj0 +uNGn7GMQXLxalpCkz4SXRg== +-----END PRIVATE KEY----- +``` +处理后: +```language +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDCjDQA8SH0X3W++0DOXtUWZdEA4aGWj7bYpf6uoLfOIaDj7IiTx68AvVP3tcS4rWG6pwCn6ng8gba39FvcUEP69UkahcqzIsIxSZPhLLn9NGFvdMzQId5+8xlNIzBxXMpPTsO3HIaAVmP1axRhlasFQ9y7S8PqzublB7eoUklZV5Ffw0OdUDHJLOvPhsjj7Wq+3J7L+5qncjq3HFHFSUhozJOwPymXre7Xh0PYUdEzolje2Z0SkEQxYj3WqZhuX0eQf8Ppe26aDQebOHTpt2uU7dg2xymvqI3a6DrIY20CHj+6Dg/hlX2fEiZyPyXw+3eOKjU7Qgil/gxQIwP4Ls+tAgMBAAECggEAaQOlTpza5z5gIKcfZEZsX5q2JvOkddE9sdRolXrLvMkKP/39+0def9ey65OCjO2KQ2bCQ+Gc5YxfRQzySQpKp7yfqWFu+SNaD6DX4kRyYOtVbQRvSin+ICi5D5pfG9IqooSxwLX1JHF9o4wZhFN17XGkRLWxG55zpE12JbXFQiPBpck6hcMfx+r5wk7t4ret/8P/MDcyrPuUavJemd4D2jRrD7AmOGJDvElioFcOKA+VS8oe/uBdpU8cbYJvct68fHOzG9IW3hdqYV18fhNtWqp9WeuUP+F2UMmOXbAtZ106Zcd+V/jsse2G9KvGzmDA61ZGxzHUjt+JNIpN+V2HQQKBgQDkfYb8vIMc2yV0CM30mAaPIapgpw8brYS8v+azQR/jjsuHFJ1CQJAih79y2gwdjKbDl0XByjj/qiHLTPcu6dkuavdsV9MrlFfVqAXUMNDHrWEn5nMahlq3UZbflBqlavTr0gvEA8Da+ZXcRvWgTP5+g5RFrKHJVOyQ+GzgDggQawKBgQDZ+IDRthf0UHvvZsoUbeb37Wut9jdjRgLJS1X4RtH+NPN23lvtTKJmUNfrFxiOfeVBfCXmGep0ibTqDVo0zBeHSu4BFM3BsICu7xafmLafZxZqHcgWuF9keOCWjKN5fzub5xGqd2yge9hGN2zA2U9qp4mltGzeoZ/0TuLuR59GRwKBgCGga7ZUVANyKQ/rn8vod8am0LlKvMl4/vj8UQp+gh/uSvvFR+ORNuUuDznq5y+OHJjacXS0uzC9LB4MZLBtz/2p1mIGhth6C3cxNDJnQMKyPIMvwi7cKQujoU2kMUu48vSlw/+EAeT4KFrzwoBl9GpQGQkr/99udSZcuUE8L2mjAoGAPRLnLVuDTL58a3D2sFC3BcLth/nUPSmxwCsutHlLf5ngme7l/RCa9GY0ibeX9t0JrpaVm+qpCexH18jT/LUu5oa1N3JX0Kye8eUmBqPoj7N30VX06YDRobpI24Yei/19e0p8ZbI+qpzo1YvUGhkJqo21AMwUMTFCO1cbOL6yvyMCgYAHUNBLhSOaIZpvbmyh5uz5Va/IIYU5nJcVAan8ExzdVBqeiDqlIDsUt/4xoV2sWOK1lDmL1QYeOOTOHdVcSUyNZpvB3b/9RZ1bNQZA1trBBxjY7dXNwZZp0ah/bmO+i4dPXl+bU2mUqdyb1emFwcj0uNGn7GMQXLxalpCkz4SXRg== +-----END PRIVATE KEY----- +``` + + +5. (可选)将pem内容进行 base64 编码后,配置到k8s + +echo -n '-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwow0APEh9F91vvtAzl7VFmXRAOGhlo+22KX+rqC3ziGg4+yIk8evAL1T97XEuK1huqcAp+p4PIG2t/Rb3FBD+vVJGoXKsyLCMUmT4Sy5/TRhb3TM0CHefvMZTSMwcVzKT07DtxyGgFZj9WsUYZWrBUPcu0vD6s7m5Qe3qFJJWVeRX8NDnVAxySzrz4bI4+1qvtyey/uap3I6txxRxUlIaMyTsD8pl63u14dD2FHRM6JY3tmdEpBEMWI91qmYbl9HkH/D6Xtumg0Hmzh06bdrlO3YNscpr6iN2ug6yGNtAh4/ug4P4ZV9nxImcj8l8Pt3jio1O0IIpf4MUCMD+C7PrQIDAQAB +-----END PUBLIC KEY-----' |base64 + + +echo -n '-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDCjDQA8SH0X3W++0DOXtUWZdEA4aGWj7bYpf6uoLfOIaDj7IiTx68AvVP3tcS4rWG6pwCn6ng8gba39FvcUEP69UkahcqzIsIxSZPhLLn9NGFvdMzQId5+8xlNIzBxXMpPTsO3HIaAVmP1axRhlasFQ9y7S8PqzublB7eoUklZV5Ffw0OdUDHJLOvPhsjj7Wq+3J7L+5qncjq3HFHFSUhozJOwPymXre7Xh0PYUdEzolje2Z0SkEQxYj3WqZhuX0eQf8Ppe26aDQebOHTpt2uU7dg2xymvqI3a6DrIY20CHj+6Dg/hlX2fEiZyPyXw+3eOKjU7Qgil/gxQIwP4Ls+tAgMBAAECggEAaQOlTpza5z5gIKcfZEZsX5q2JvOkddE9sdRolXrLvMkKP/39+0def9ey65OCjO2KQ2bCQ+Gc5YxfRQzySQpKp7yfqWFu+SNaD6DX4kRyYOtVbQRvSin+ICi5D5pfG9IqooSxwLX1JHF9o4wZhFN17XGkRLWxG55zpE12JbXFQiPBpck6hcMfx+r5wk7t4ret/8P/MDcyrPuUavJemd4D2jRrD7AmOGJDvElioFcOKA+VS8oe/uBdpU8cbYJvct68fHOzG9IW3hdqYV18fhNtWqp9WeuUP+F2UMmOXbAtZ106Zcd+V/jsse2G9KvGzmDA61ZGxzHUjt+JNIpN+V2HQQKBgQDkfYb8vIMc2yV0CM30mAaPIapgpw8brYS8v+azQR/jjsuHFJ1CQJAih79y2gwdjKbDl0XByjj/qiHLTPcu6dkuavdsV9MrlFfVqAXUMNDHrWEn5nMahlq3UZbflBqlavTr0gvEA8Da+ZXcRvWgTP5+g5RFrKHJVOyQ+GzgDggQawKBgQDZ+IDRthf0UHvvZsoUbeb37Wut9jdjRgLJS1X4RtH+NPN23lvtTKJmUNfrFxiOfeVBfCXmGep0ibTqDVo0zBeHSu4BFM3BsICu7xafmLafZxZqHcgWuF9keOCWjKN5fzub5xGqd2yge9hGN2zA2U9qp4mltGzeoZ/0TuLuR59GRwKBgCGga7ZUVANyKQ/rn8vod8am0LlKvMl4/vj8UQp+gh/uSvvFR+ORNuUuDznq5y+OHJjacXS0uzC9LB4MZLBtz/2p1mIGhth6C3cxNDJnQMKyPIMvwi7cKQujoU2kMUu48vSlw/+EAeT4KFrzwoBl9GpQGQkr/99udSZcuUE8L2mjAoGAPRLnLVuDTL58a3D2sFC3BcLth/nUPSmxwCsutHlLf5ngme7l/RCa9GY0ibeX9t0JrpaVm+qpCexH18jT/LUu5oa1N3JX0Kye8eUmBqPoj7N30VX06YDRobpI24Yei/19e0p8ZbI+qpzo1YvUGhkJqo21AMwUMTFCO1cbOL6yvyMCgYAHUNBLhSOaIZpvbmyh5uz5Va/IIYU5nJcVAan8ExzdVBqeiDqlIDsUt/4xoV2sWOK1lDmL1QYeOOTOHdVcSUyNZpvB3b/9RZ1bNQZA1trBBxjY7dXNwZZp0ah/bmO+i4dPXl+bU2mUqdyb1emFwcj0uNGn7GMQXLxalpCkz4SXRg== +-----END PRIVATE KEY-----' |base64 diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/0.token-server-base.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/0.token-server-base.yaml new file mode 100644 index 0000000..aeda1f2 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/0.token-server-base.yaml @@ -0,0 +1,143 @@ +# 0.token-server-base.yaml + +#################################################### +# harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: token-server-test + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 + + +#################################################### +# redis-server +#################################################### +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: token-server-test + name: redis-server + labels: + app: redis + release: redis-server +type: Opaque +data: + REDIS_PASSWORD: OEt1d29zbE9pdXc3SA== +--- +apiVersion: v1 +kind: Service +metadata: + namespace: token-server-test + name: redis-server + labels: + app: redis + release: redis-server +spec: + ports: + - name: redis + port: 6379 + protocol: TCP + targetPort: redis + selector: + app: redis + release: redis-server + role: master + type: ClusterIP +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: token-server-test + name: redis-server + labels: + app: redis + release: redis-server +spec: + podManagementPolicy: OrderedReady + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: redis + release: redis-server + role: master + serviceName: redis-master + template: + metadata: + labels: + app: redis + release: redis-server + role: master + spec: + containers: + - name: redis-server + env: + - name: REDIS_DISABLE_COMMANDS + value: FLUSHDB,FLUSHALL + - name: REDIS_REPLICATION_MODE + value: master + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-server + key: REDIS_PASSWORD + # 若使用了学校搭设的私有仓库,请修改 + image: bitnami/redis:4.0 + # 若使用了学校搭设的私有仓库,请修改 为 Always + imagePullPolicy: IfNotPresent + # imagePullPolicy: Always + livenessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - containerPort: 6379 + name: redis + protocol: TCP + readinessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 5 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + volumeMounts: + - mountPath: /bitnami/redis/data + name: redis-data + dnsPolicy: ClusterFirst + restartPolicy: Always + securityContext: + fsGroup: 0 + # fsGroup: 1001 + # runAsUser: 1001 + # https://github.com/bitnami/bitnami-docker-redis/issues/106#issuecomment-388884372 + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - emptyDir: {} + name: redis-data + # 若使用了学校搭设的私有仓库,请增加以下配置(取消注释即可) + # imagePullSecrets: + # - name: harbor-registry + updateStrategy: + rollingUpdate: + partition: 0 + type: RollingUpdate + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/1.token-server-env.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/1.token-server-env.yaml new file mode 100644 index 0000000..684344b --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/1.token-server-env.yaml @@ -0,0 +1,38 @@ +# 1.token-server-env.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: token-server-test + name: jvm-env +data: + MAX_RAM_PERCENTAGE: "75.0" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: token-server-test + name: datasource-env-secret +type: Opaque +data: + # jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/token_server?serverTimezone=Asia/Shanghai + JDBC_URL: amRiYzpteXNxbDovL215c3FsLXNlcnZlci5hdXRoeC1zZXJ2aWNlLXRlc3Quc3ZjLmNsdXN0ZXIubG9jYWw6MzMwNi90b2tlbl9zZXJ2ZXI/c2VydmVyVGltZXpvbmU9QXNpYS9TaGFuZ2hhaQ== + # token_server + JDBC_USERNAME: dG9rZW5fc2VydmVy + # 修改为实际的数据库密码,并使用 base64 工具进行编码 + # Nwpu@Supwisdom123 + JDBC_PASSWORD: TndwdUBTdXB3aXNkb20xMjM= + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: token-server-test + name: redis-env-secret +type: Opaque +data: + SPRING_REDIS_HOST: cmVkaXMtc2VydmVy + SPRING_REDIS_PORT: NjM3OQ== + SPRING_REDIS_PASSWORD: OEt1d29zbE9pdXc3SA== diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/2.token-server-ingresses.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/2.token-server-ingresses.yaml new file mode 100644 index 0000000..78c316c --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/2.token-server-ingresses.yaml @@ -0,0 +1,23 @@ +# 2.token-server-ingresses.yaml + + +# 移动端应用认证服务 +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + namespace: token-server-test + name: token-server-ingress + annotations: + nginx.ingress.kubernetes.io/proxy-buffer-size: "8k" +spec: + rules: + # 修改为学校的根域名 + - host: token-test.paas.newcapec.cn + http: + paths: + - path: / + backend: + serviceName: token-server-svc + servicePort: http + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/4.0.token-server-installer.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/4.0.token-server-installer.yaml new file mode 100644 index 0000000..4a48a3d --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/4.0.token-server-installer.yaml @@ -0,0 +1,47 @@ +# 4.0.token-server-installer.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: token-server-test + name: token-server-installer-env +data: + DB_TYPE: mysql8 + + +--- +apiVersion: batch/v1 +kind: Job +metadata: + namespace: token-server-test + name: token-server-installer +spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: token-server-installer + spec: + restartPolicy: Never + containers: + - name: token-server-installer + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/token-server/token-server-installer:1.0.0-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: token-server-installer-env + resources: + requests: + memory: "256Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/4.1.token-server.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/4.1.token-server.yaml new file mode 100644 index 0000000..dbf24f4 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/5.token-server/4.1.token-server.yaml @@ -0,0 +1,176 @@ +# 4.1.token-server.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: token-server-test + name: token-server-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEY_PASSWORD: "" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + SERVER_TOMCAT_ACCEPT_COUNT: "5000" + SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + SERVER_TOMCAT_MAX_THREADS: "800" + SERVER_TOMCAT_MIN_SPARE_THREADS: "100" + + SPRING_REDIS_JEDIS_POOL_MAXACTIVE: "800" + SPRING_REDIS_JEDIS_POOL_MAXIDLE: "100" + SPRING_REDIS_JEDIS_POOL_MINIDLE: "100" + + + # **修改** 从消息中心申请 + MESSAGECENTER_ENABLED: "false" + MESSAGECENTER_APP_ID: "" + MESSAGECENTER_MESSAGE_TYPE_CODE_APP_LOGIN: APP_LOGIN + + # **修改** 从POA申请 + POA_SERVER_URL: https://poa-test.paas.newcapec.cn + POA_CLIENT_ID: "" + POA_CLIENT_SECRET: "" + POA_SCOPES: messagecenter:v1:sendMessage + + + # **修改** 学校的根域名 + TOKEN_SERVER_PREFIX: https://token-test.paas.newcapec.cn + # **修改** 学校的根域名 + TOKEN_SERVER_SECURITY_JWT_ISS: token-test.paas.newcapec.cn + #TOKEN_SERVER_SECURITY_JWT_EXPIRATION: 2592000 + #TOKEN_SERVER_SECURITY_JWT_KICKOUT_ENABLED: "false" + # **修改** + # 请使用与 cas-server 一致的公私钥 + TOKEN_SERVER_SECURITY_JWT_PRIVATE_KEY_PEM_PKCS8: "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDKivcJfoDpTgShIdrC0AuImgHQKQmdv/CZWRxVPkSY26kZWtVJ4mjzRkDGyB31LUJlVfFNe0nteOyqfNHrhC+uf612+P0KTmT/pOenoegpT8BDEDe1DlmrDoPqKE87JVXjPhx0rnCPMQE0+Em5OOPM/hVDiHhWx5Y1t+FcYre9J6zyg2flbCiv2vVRsQk/9kwesMnEBzB7QY+95sCoSng7llxO1aer7+qShQHrP/nYScIyW2g+a4wL6jd9Z0gIF/irvShIMKV+6EtWLiZFPYrlRQfx+zER7qg+2S+T29UII5lGajQxeldmIip1k62BwHOf/SbOg13nwrF4jLSCKeN/AgMBAAECggEAVtWHHcHngJ6bK325LSZGm5TzTAwb/E6q1wO2OvGMNUCPWbhwktGHjyzCXray6UczHQDgiAhgZHggduM2mFM+ogBJHSWYTo/XiyZmzp6CSxvO4LGWQIBbfxOlCIGpnkDedqNNTdTvmuQ2kUAVU1yJhXw1H5Pli8bbpkIkUxhbj7MsmcSZS4Xaqj1jhOWoBzt1SZEpHgDZ4m8MEMBfjLu+/SQAIWGdJmyANdsU3V/f/DmcgSqu7oTFYZiEFyJqTRyCVHJmyIqAOAtqHkKnJcGfeurwUIuX5NVqdYhj/JM+3k8lXDRyoyC0QADhnfR85uXV/OnXCVBC8GABuMP4DaiHyQKBgQDjwjtbVb/jQur2JYsSDS0sZI3S4X929gWU66AyClnUNbRIVcN4Lyhnp8+d/m9+oVV6kDfjTDnuEz7TWHr94RFcecdivehzxRHdRlRp+IhmtCtzstPhS5f0U6/e59CryxgxV+h5jDUssokzdz1bLsnC8+VgKNL2jVXqkuLkF3RqhQKBgQDjqE186VX3oej5YlmLmqi4LVFFVzpX75dOjAFc+ke/SPXm11o7lj1ONr+t9ZKcwvPx9j5OPXJajbaE2Qx1KXzTPKQT44GdpOvistOJQSNpx2e00K4Sn/7bsJq++UJ7FtmR+iJvfYq1uW1z5taVIjh5hhwFtIBW38voNcghCXVvMwKBgAUwRpPlFzMBMkMbRdjKbg4F2GlGc9Xs8uGaoJKjQ7qe4pWHRqW1RVFfNE6gHkAfQshBAtTtxqAS1iqQaHTiLLgTmiQ4uVPx2F9XG9MyM0FLt3WyTDtksniBc487briLLujo3MXwGMIE6zU98SrjnPsQ/Ve8dlnhjGSEpiCWHDPVAoGAZwNmJMqUytvpxsbZDBGsnMJszvqcfOP+TF2P1FmwE39ZPd5ehy4BiZ2+eGHxuJuCtQ8evFqTnyQW3eA1AeMHB7Kd8B33LbVNw6P1klr2QkwnwirXSbg6I4CzVQ0HJxl809Aiut5M4NQKEfL3UD5O3bZwgahelnDoHKgRadmU2P8CgYANBbxpDT1SdyJUFuKzJ5/cUPBFzOn3eNGRo/RejXSCi5Spd9OoTwDh6dbffk7pUWLYH/BFILW9+RL8uhMt8mdTWVgDKrNrdZLdWUBNsb89St9x/JwlucqgbTvzf0G0h/ZiGNzyPhgGABRrlWVYIdS8KLdTYUkvPHsEAtxR+kwTAg==" + TOKEN_SERVER_SECURITY_JWT_PUBLIC_KEY_PEM: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyor3CX6A6U4EoSHawtALiJoB0CkJnb/wmVkcVT5EmNupGVrVSeJo80ZAxsgd9S1CZVXxTXtJ7XjsqnzR64Qvrn+tdvj9Ck5k/6Tnp6HoKU/AQxA3tQ5Zqw6D6ihPOyVV4z4cdK5wjzEBNPhJuTjjzP4VQ4h4VseWNbfhXGK3vSes8oNn5Wwor9r1UbEJP/ZMHrDJxAcwe0GPvebAqEp4O5ZcTtWnq+/qkoUB6z/52EnCMltoPmuMC+o3fWdICBf4q70oSDClfuhLVi4mRT2K5UUH8fsxEe6oPtkvk9vVCCOZRmo0MXpXZiIqdZOtgcBzn/0mzoNd58KxeIy0ginjfwIDAQAB" + + + # face + # aiface 新开普人脸,aipface 百度人脸 + TOKEN_SERVER_FACE_SOURCE_TYPE: aiface + + # 若须对接新开普人脸,须由新开普人脸系统提供相关配置 + TOKEN_SERVER_FACE_AIFACE_URL: "" + TOKEN_SERVER_FACE_AIFACE_APPKEY: "" + TOKEN_SERVER_FACE_AIFACE_APPSECRET: "" + TOKEN_SERVER_FACE_AIFACE_SECRETKEY: "" + TOKEN_SERVER_FACE_AIFACE_TERM_CODE: "" + + # 若须对接百度人脸,须在百度开放平台注册应用 + TOKEN_SERVER_FACE_AIPFACE_APPID: "" + TOKEN_SERVER_FACE_AIPFACE_APIKEY: "" + TOKEN_SERVER_FACE_AIPFACE_SECRETKEY: "" + + + # passwordless + TOKEN_SERVER_PASSWORDLESS_TOKEN_EXPIRATION_IN_SECONDS: "300" + TOKEN_SERVER_PASSWORDLESS_SMS_TEXT_TEMPLATE: 【认证中心】{name}:您正在进行登录,本次登录的动态密码为{token},有效期5分钟,请尽快完成登录。 + TOKEN_SERVER_PASSWORDLESS_SMS_FROM: 认证中心 + + + CASSERVER_SA_API_SERVER_URL: http://cas-server-sa-api-svc.cas-server-test.svc.cluster.local:8080 + CASSERVER_SA_API_CLIENT_AUTH_ENABLED: "false" + #CASSERVER_SA_API_CLIENT_AUTH_KEY_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + USER_DATA_SERVICE_SA_API_SERVER_URL: http://user-data-service-goa-svc.user-data-service-test.svc.cluster.local:8080 + USER_DATA_SERVICE_SA_API_CLIENT_AUTH_ENABLED: "false" + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #USER_DATA_SERVICE_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + + TPAS_AGENT_SERVICE_SERVER_URL: http://agent-service-svc.thirdparty-agent-service-test.svc.cluster.local:8080 + TPAS_AGENT_SERVICE_CLIENT_AUTH_ENABLED: "false" + #TPAS_AGENT_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #TPAS_AGENT_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #TPAS_AGENT_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #TPAS_AGENT_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #TPAS_AGENT_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + TPAS_AGENT_SERVICE_SMS_SENDER_PATH: /api/v1/tpas/sms/console/send + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: token-server-test + name: token-server-svc + labels: + app: token-server + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: token-server + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: token-server-test + name: token-server +spec: + selector: + matchLabels: + app: token-server + replicas: 1 + template: + metadata: + labels: + app: token-server + spec: + containers: + - name: token-server + # 若使用了学校搭设的私有仓库,请 **修改** + image: harbor.supwisdom.com/token-server/token-server:1.0.0-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - secretRef: + name: redis-env-secret + - configMapRef: + name: token-server-env + resources: + requests: + memory: "512Mi" + limits: + memory: "512Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/0.personal-security-center-base.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/0.personal-security-center-base.yaml new file mode 100644 index 0000000..fc26858 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/0.personal-security-center-base.yaml @@ -0,0 +1,144 @@ +# personal-security-center-base.yaml + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: personal-security-center-test + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 + + +#################################################### +# redis-server +#################################################### + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: personal-security-center-test + name: redis-server + labels: + app: redis + release: redis-server +type: Opaque +data: + REDIS_PASSWORD: OEt1d29zbE9pdXc3SA== + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: personal-security-center-test + name: redis-server + labels: + app: redis + release: redis-server +spec: + ports: + - name: redis + port: 6379 + protocol: TCP + targetPort: redis + selector: + app: redis + release: redis-server + role: master + type: ClusterIP +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: personal-security-center-test + name: redis-server + labels: + app: redis + release: redis-server +spec: + podManagementPolicy: OrderedReady + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: redis + release: redis-server + role: master + serviceName: redis-master + template: + metadata: + labels: + app: redis + release: redis-server + role: master + spec: + containers: + - name: redis-server + env: + - name: REDIS_DISABLE_COMMANDS + value: FLUSHDB,FLUSHALL + - name: REDIS_REPLICATION_MODE + value: master + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-server + key: REDIS_PASSWORD + # 若使用了学校搭设的私有仓库,请修改 + image: bitnami/redis:4.0 + # 若使用了学校搭设的私有仓库,请修改 为 Always + imagePullPolicy: IfNotPresent + # imagePullPolicy: Always + livenessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - containerPort: 6379 + name: redis + protocol: TCP + readinessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 5 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + volumeMounts: + - mountPath: /bitnami/redis/data + name: redis-data + dnsPolicy: ClusterFirst + restartPolicy: Always + securityContext: + fsGroup: 1001 + # runAsUser: 1001 + # https://github.com/bitnami/bitnami-docker-redis/issues/106#issuecomment-388884372 + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - emptyDir: {} + name: redis-data + # 若使用了学校搭设的私有仓库,请增加以下配置(取消注释即可) + # imagePullSecrets: + # - name: harbor-registry + updateStrategy: + rollingUpdate: + partition: 0 + type: RollingUpdate + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/1.personal-security-center-env.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/1.personal-security-center-env.yaml new file mode 100644 index 0000000..09f2982 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/1.personal-security-center-env.yaml @@ -0,0 +1,22 @@ +# personal-security-center-env.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: personal-security-center-test + name: jvm-env +data: + MAX_RAM_PERCENTAGE: "75.0" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: personal-security-center-test + name: redis-env-secret +type: Opaque +data: + SPRING_REDIS_HOST: cmVkaXMtc2VydmVy + SPRING_REDIS_PORT: NjM3OQ== + SPRING_REDIS_PASSWORD: OEt1d29zbE9pdXc3SA== diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/2.personal-security-center-ingresses.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/2.personal-security-center-ingresses.yaml new file mode 100644 index 0000000..1835d17 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/2.personal-security-center-ingresses.yaml @@ -0,0 +1,41 @@ +# personal-security-center-ingresses.yaml + + +# 个人中心后端接口 +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + namespace: personal-security-center-test + name: personal-security-center-ingress + annotations: + nginx.ingress.kubernetes.io/proxy-buffer-size: "8k" +spec: + rules: + # 修改为学校的根域名 + - host: personal-security-center-test.paas.newcapec.cn + http: + paths: + - path: / + backend: + serviceName: personal-security-center-zuul-svc + servicePort: http + + +# 安全中心前端 +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + namespace: personal-security-center-test + name: security-center-ui-ingress +spec: + rules: + # 修改为学校的根域名 + - host: security-center-test.paas.newcapec.cn + http: + paths: + - path: / + backend: + serviceName: security-center-ui-svc + servicePort: http diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.4.personal-security-center-bff.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.4.personal-security-center-bff.yaml new file mode 100644 index 0000000..49f640a --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.4.personal-security-center-bff.yaml @@ -0,0 +1,225 @@ +# personal-security-center-bff.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: personal-security-center-test + name: personal-security-center-bff-template-env +data: + # 根据情况,修改邮件模板 + EMAIL_TEMPLATE_ACTIVE_USER_SEND_CODE_BY_EMAIL_ADDRESS: '{name}:您正在激活帐号,须验证邮箱有效,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_FORGOT_PASSWORD_SEND_CODE: '{name}:您正在找回密码,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + + EMAIL_TEMPLATE_USER_SECURITY_PASSWORD_SEND_CODE: '{name}:您正在修改密码,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_USER_SECURITY_EMAIL_ADDRESS_SEND_CODE: '{name}:您正在修改安全邮箱,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_USER_SECURITY_EMAIL_ADDRESS_SEND_CODE_BY_EMAIL_ADDRESS: '{name}:您正在修改安全邮箱,须验证邮箱有效,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_USER_SECURITY_MOBILE_SEND_CODE: '{name}:您正在修改安全手机,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + + EMAIL_TEMPLATE_USER_FEDERATION_QQ_SEND_CODE: '{name}:您正在绑定QQ,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_USER_FEDERATION_QQ_SEND_CODE_UNBIND_QQ: '{name}:您正在解绑QQ,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_USER_FEDERATION_OPENWEIXIN_SEND_CODE: '{name}:您正在绑定微信,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_USER_FEDERATION_OPENWEIXIN_SEND_CODE_UNBIND_OPENWEIXIN: '{name}:您正在解绑微信,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_USER_FEDERATION_WORKWEIXIN_SEND_CODE: '{name}:您正在绑定企业微信,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_USER_FEDERATION_WORKWEIXIN_SEND_CODE_UNBIND_WORKWEIXIN: '{name}:您正在解绑企业微信,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_USER_FEDERATION_ALIPAY_SEND_CODE: '{name}:您正在绑定支付宝,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + EMAIL_TEMPLATE_USER_FEDERATION_ALIPAY_SEND_CODE_UNBIND_ALIPAY: '{name}:您正在解绑支付宝,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + + # 根据情况,修改短信模板 + SMS_TEMPLATE_ACTIVE_USER_SEND_CODE_BY_PRE_MOBILE: '{prefix}{name}:您正在激活帐号,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_ACTIVE_USER_SEND_CODE_BY_MOBILE: '{prefix}{name}:您正在激活帐号,须验证手机有效,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_FORGOT_PASSWORD_SEND_CODE: '{prefix}{name}:您正在找回密码,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + + SMS_TEMPLATE_USER_SECURITY_PASSWORD_SEND_CODE: '{prefix}{name}:您正在修改密码,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_USER_SECURITY_EMAIL_ADDRESS_SEND_CODE: '{prefix}{name}:您正在修改安全邮箱,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_USER_SECURITY_MOBILE_SEND_CODE: '{prefix}{name}:您正在修改安全手机,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_USER_SECURITY_MOBILE_SEND_CODE_BY_MOBILE: '{prefix}{name}:您正在修改安全手机,须验证手机有效,验证码{code},有效期5分钟,请尽快完成验证。' + + SMS_TEMPLATE_USER_FEDERATION_QQ_SEND_CODE: '{prefix}{name}:您正在绑定QQ,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_USER_FEDERATION_QQ_SEND_CODE_UNBIND_QQ: '{prefix}{name}:您正在解绑QQ,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_USER_FEDERATION_OPENWEIXIN_SEND_CODE: '{prefix}{name}:您正在绑定微信,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_USER_FEDERATION_OPENWEIXIN_SEND_CODE_UNBIND_OPENWEIXIN: '{prefix}{name}:您正在解绑微信,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_USER_FEDERATION_WORKWEIXIN_SEND_CODE: '{prefix}{name}:您正在绑定企业微信,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_USER_FEDERATION_WORKWEIXIN_SEND_CODE_UNBIND_WORKWEIXIN: '{prefix}{name}:您正在解绑企业微信,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_USER_FEDERATION_ALIPAY_SEND_CODE: '{prefix}{name}:您正在绑定支付宝,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + SMS_TEMPLATE_USER_FEDERATION_ALIPAY_SEND_CODE_UNBIND_ALIPAY: '{prefix}{name}:您正在解绑支付宝,须验证身份,验证码{code},有效期5分钟,请尽快完成验证。' + + SMS_TEMPLATE_PREFIX: '' + + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: personal-security-center-test + name: personal-security-center-bff-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + SERVER_TOMCAT_ACCEPT_COUNT: "5000" + SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + SERVER_TOMCAT_MAX_THREADS: "800" + SERVER_TOMCAT_MIN_SPARE_THREADS: "100" + + SPRING_REDIS_JEDIS_POOL_MAXACTIVE: "800" + SPRING_REDIS_JEDIS_POOL_MAXIDLE: "100" + SPRING_REDIS_JEDIS_POOL_MINIDLE: "100" + + LOGGING_LEVEL_COM_SUPWISDOM_INSTITUTE_PERSONAL_SECURITY_CENTER_BFF: INFO + + + # 修改为学校的 personal-security-center 的访问域名 + PERSONAL_SECURITY_CENTER_SERVER_PREFIX: https://personal-security-center-test.newcapec.edu.cn + # 修改为学校的 cas 的访问域名 + CAS_SERVER_PREFIX: https://cas-test.paas.newcapec.cn/cas + + PERSONAL_SECURITY_BFF_NONCE_STORE_IMPL: redis + + + # 新开普人脸对接配置 + # 修改为实际项目配置 + PERSONAL_SECURITY_BFF_FACE_AIFACE_URL: "http://117.158.17.228:3003/aiface" + PERSONAL_SECURITY_BFF_FACE_AIFACE_APPKEY: "GcacXnw46DxMAApNoSTX" + PERSONAL_SECURITY_BFF_FACE_AIFACE_APPSECRET: "eXl15kcYGBdCYTOCFD21" + PERSONAL_SECURITY_BFF_FACE_AIFACE_SECRETKEY: "12345678abcdefgh87654321" + PERSONAL_SECURITY_BFF_FACE_AIFACE_TERM_CODE: "12" + + + CASSERVER_SITE_SERVER_URL: http://cas-server-site-webapp-svc.cas-server-test.svc.cluster.local:8080/cas + CASSERVER_SITE_CLIENT_AUTH_ENABLED: "false" + #CASSERVER_SITE_CLIENT_AUTH_KEY_PASSWORD: "" + #CASSERVER_SITE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #CASSERVER_SITE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #CASSERVER_SITE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #CASSERVER_SITE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + CASSERVER_SA_API_SERVER_URL: http://cas-server-sa-api-svc.cas-server-test.svc.cluster.local:8080 + CASSERVER_SA_API_CLIENT_AUTH_ENABLED: "false" + #CASSERVER_SA_API_CLIENT_AUTH_KEY_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + USER_DATA_SERVICE_SERVER_URL: http://user-data-service-goa-svc.user-data-service-test.svc.cluster.local:8080 + USER_DATA_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_DATA_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + + TPAS_FILE_API_URL: http://agent-service-svc.thirdparty-agent-service-test.svc.cluster.local:8080/api/v1/tpas/file/db + TPAS_MAIL_API_URL: http://agent-service-svc.thirdparty-agent-service-test.svc.cluster.local:8080/api/v1/tpas/mail/smtp + TPAS_SMS_API_URL: http://agent-service-svc.thirdparty-agent-service-test.svc.cluster.local:8080/api/v1/tpas/sms/console + TPAS_CLIENT_AUTH_ENABLED: "false" + #TPAS_CLIENT_AUTH_KEY_PASSWORD: "" + #TPAS_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #TPAS_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #TPAS_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #TPAS_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + + # COMMUNICATOR_EMAIL_MAIL_SERVER_HOST: "smtp.supwisdom.com" + # COMMUNICATOR_EMAIL_MAIL_SERVER_PORT: "25" + # COMMUNICATOR_EMAIL_USER_NAME: "security.institute@supwisdom.com" + # COMMUNICATOR_EMAIL_PASSWORD: "Security2019" + # COMMUNICATOR_EMAIL_VALIDATE: "true" + + # COMMUNICATOR_SMS_SENDER_URL: https://agent-service-api.supwisdom.com/api/v1/tpas/sms/console/send + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: personal-security-center-test + name: personal-security-center-bff-env-secret +type: Opaque +data: + + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: personal-security-center-test + name: personal-security-center-bff-svc + labels: + app: personal-security-center-bff + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: personal-security-center-bff + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: personal-security-center-test + name: personal-security-center-bff +spec: + selector: + matchLabels: + app: personal-security-center-bff + replicas: 1 + template: + metadata: + labels: + app: personal-security-center-bff + spec: + containers: + - name: personal-security-center-bff + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/personal-security-center/personal-security-bff:1.0.2-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: redis-env-secret + - secretRef: + name: personal-security-center-bff-env-secret + - configMapRef: + name: personal-security-center-bff-env + - configMapRef: + name: personal-security-center-bff-template-env + resources: + requests: + memory: "1024Mi" + limits: + memory: "1024Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.5.personal-security-center-zuul.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.5.personal-security-center-zuul.yaml new file mode 100644 index 0000000..b031443 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.5.personal-security-center-zuul.yaml @@ -0,0 +1,169 @@ +# personal-security-center-zuul.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: personal-security-center-test + name: personal-security-center-zuul-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + SERVER_TOMCAT_ACCEPT_COUNT: "5000" + SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + SERVER_TOMCAT_MAX_THREADS: "800" + SERVER_TOMCAT_MIN_SPARE_THREADS: "100" + + ZUUL_HOST_MAX_PER_ROUTE_CONNECTIONS: "1000" + ZUUL_HOST_MAX_TOTAL_CONNECTIONS: "1000" + + ZUUL_SEMAPHORE_MAX_SEMAPHORES: "10000" + + LOGGING_LEVEL_COM_SUPWISDOM_INSTITUTE_PERSONAL_SECURITY_CENTER: INFO + + + ZUUL_ROUTES_PERSONAL_ME_URL: http://personal-security-center-bff-svc.personal-security-center-test.svc.cluster.local:8080/api/v1/me + ZUUL_ROUTES_PERSONAL_BFF_URL: http://personal-security-center-bff-svc.personal-security-center-test.svc.cluster.local:8080/api/v1 + + ZUUL_ROUTES_USER_BIZ_URL: http://user-data-service-biz-svc.user-data-service-test.svc.cluster.local:8080/api/v1/user/biz + + # 修改为学校的 portal 的访问域名 + ZUUL_ROUTES_PORTAL_URL: https://portal.paas.newcapec.cn/portal-web/api + + + INFRAS_SECURITY_BASIC_ENABLED: "false" + + INFRAS_SECURITY_JWT_ENABLED: "true" + #INFRAS_SECURITY_JWT_KEY_ALIAS: "supwisdom-jwt-key" + #INFRAS_SECURITY_JWT_KEY_PASSWORD: "changeit" + #INFRAS_SECURITY_JWT_KEY_STORE: "file:/certs/jwt/jwt.keystore" + #INFRAS_SECURITY_JWT_KEY_STORE_PASSWORD: "changeit" + + INFRAS_SECURITY_JWT_TOKEN_GENERATE_TYPE: cas + INFRAS_SECURITY_JWT_TOKEN_DECRYPT_KEY_PRIVATE_KEY_PEM_PKCS8: "" + INFRAS_SECURITY_JWT_TOKEN_SIGNING_KEY_URL: "http://cas-server-site-webapp-svc.cas-server-test.svc.cluster.local:8080/cas/jwt/publicKey" + + + INFRAS_SECURITY_CAS_ENABLED: "true" + # 修改为学校的 personal-security-center 的访问域名 + APP_SERVER_HOST_URL: "https://personal-security-center-test.paas.newcapec.cn" + #APP_LOGIN_URL: "/cas/login" + #APP_LOGOUT_URL: "/cas/logout" + # 修改为学校的 cas 的访问域名 + CAS_SERVER_HOST_URL: "https://cas-test.paas.newcapec.cn/cas" + + + ZUUL_HTTPCLIENT_CLIENT_AUTH_ENABLED: "false" + #ZUUL_HTTPCLIENT_CLIENT_AUTH_KEY_PASSWORD: "" + #ZUUL_HTTPCLIENT_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #ZUUL_HTTPCLIENT_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + + + USER_DATA_SERVICE_SERVER_URL: http://user-data-service-goa-svc.user-data-service-test.svc.cluster.local:8080 + USER_DATA_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_DATA_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + USER_AUTHZ_SERVICE_SERVER_URL: http://user-authorization-sa-svc.user-authorization-service-test.svc.cluster.local:8080 + USER_AUTHZ_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #USER_AUTHZ_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: personal-security-center-test + name: personal-security-center-zuul-env-secret +type: Opaque +data: + # 参考 certs/jwt/readme.md 生成公私钥pem,替换相关配置 + INFRAS_SECURITY_JWT_PUBLIC_KEY_PEM: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDeW9BNzhMbTlHT3NlS1pPL1lZenlWWUJ6cQpaREVzdWlXNVFleXJDL2JFWFZrT2lKc0RnNFRjc2o5Vnp5dGp2MEFZVmxEcmkxdlExaWZhSG9HN0Z1dE40cTVICllxbGZDSzdvOXpNRWo2cU40NFIydUtjR3BCQnd0WlNCZGxWc2tLZ2NOWGlvU3RTRjZZTFp1Q25jWU5HUXZaOSsKeGY5bll5L09scXczWUFQRUx3SURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ== + INFRAS_SECURITY_JWT_PRIVATE_KEY_PEM_PKCS8: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUNlQUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQW1Jd2dnSmVBZ0VBQW9HQkFMS2dEdnd1YjBZNng0cGsKNzloalBKVmdIT3BrTVN5NkpibEI3S3NMOXNSZFdRNkltd09EaE55eVAxWFBLMk8vUUJoV1VPdUxXOURXSjlvZQpnYnNXNjAzaXJrZGlxVjhJcnVqM013U1BxbzNqaEhhNHB3YWtFSEMxbElGMlZXeVFxQncxZUtoSzFJWHBndG00CktkeGcwWkM5bjM3Ri8yZGpMODZXckRkZ0E4UXZBZ01CQUFFQ2dZRUFuakhFczdDSUdlR0t3TlZkMlAwaU5ZU1cKZHp0ZWxhY1NLN3puMWlCVlhsanh1ejVlVXNGU2xJWkVNMEd6d3JZcEZLUzFLN1lURGFQc1RXOUJJNmxMb0FaawpnaU1vOUE5YnMzdW5XOEg3N2M5T3NTUXZpdHM1eGp3MEJ0dFo0dVhwYmdlUlJmS1dFOFp6MngyYWFIeVdyU1ZIClJINGVya3JYSTFrZzZwQTlyaWtDUVFEaVd0VW5kWktpWHFNTkhJb1RrOUpLNXFyaVJqdS9FTzdtVncvRGo4RmEKSVhFOTMvTkhSVllMZ3E2cFY4SUJiNmlhZnpXbittdkplR3AvbEJsaU81dHpBa0VBeWdUMTE4V25jaFl5elNlTAp3NlVDUkhIOHlJRGx6aGwzWFhxTnhDV2M5V1dGbVpZSERIVy92L2x5dnpwUEtmb3VucmhoUTVXY2g4eGVDSDVqCml1WjlWUUpCQUtsRkJkdUJSOHVXZTlaRlBsaFBsZFlmVXpEdEZxYldVZUQ4d0RRZFg1azRJd2dEWGxrdzE1eTUKK0VWNDlBTEE3bFBDeDJ3N2o3bFZERWNsaUNuMnExTUNRQnltSTI4Y0dxajFPUE1iSHBqNk41NFpSQzN6Q2FQMgp2SlRISW4ra2plUEhKL0VsODQzeXpPU2VyWVVzOGJrVVA3UkdsWlNPRFFxOUVzREZtN3hBLzVrQ1FRQ3A1ZldQCnNWbjFsek15ckYxNHJSK0ZSSWZMazBFMnBMdm5aYzV0NjB3OFpzSVFPRGlOTXZvSDRZUEdSemFpcG9LQnlSeE0KazR1WElVVTMxaVN6VGR4ZgotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0t + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: personal-security-center-test + name: personal-security-center-zuul-svc + labels: + app: personal-security-center-zuul + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: personal-security-center-zuul + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: personal-security-center-test + name: personal-security-center-zuul +spec: + selector: + matchLabels: + app: personal-security-center-zuul + replicas: 1 + template: + metadata: + labels: + app: personal-security-center-zuul + spec: + containers: + - name: personal-security-center-zuul + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/personal-security-center/personal-security-zuul:1.0.2-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: personal-security-center-zuul-env-secret + - configMapRef: + name: personal-security-center-zuul-env + resources: + requests: + memory: "512Mi" + limits: + memory: "512Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.9.security-center-ui.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.9.security-center-ui.yaml new file mode 100644 index 0000000..48d3bcc --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/4.9.security-center-ui.yaml @@ -0,0 +1,70 @@ +# 4.9.security-center-ui.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: personal-security-center-test + name: security-center-ui-env +data: + SCHOOL_NAME: sw + MAIN_SERVER: https://security-center-test.paas.newcapec.cn + + PERSONAL_CENTER_API: https://personal-security-center-test.paas.newcapec.cn + + AUTH_CAS: https://cas-test.paas.newcapec.cn/cas + JWT_ISS: https://cas-test.paas.newcapec.cn/cas + JWT_SECRET: (@K7qy)awCjxp$L653Mf$2 + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: personal-security-center-test + name: security-center-ui-svc + labels: + app: security-center-ui-svc +spec: + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: security-center-ui + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: personal-security-center-test + name: security-center-ui +spec: + selector: + matchLabels: + app: security-center-ui + replicas: 1 + template: + metadata: + labels: + app: security-center-ui + spec: + containers: + - name: security-center-ui + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/personal-security-center/security-center-ui:0.0.1 + imagePullPolicy: Always + ports: + - containerPort: 80 + name: http + envFrom: + - configMapRef: + name: security-center-ui-env + resources: + requests: + memory: "128Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/certs/jwt/readme.md b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/certs/jwt/readme.md new file mode 100644 index 0000000..3c94b3e --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/6.personal-security-center/certs/jwt/readme.md @@ -0,0 +1,83 @@ +# readme.md + + +## 使用 openssl 生成 公私钥 + + +1. 生成私钥 App Private Key + +必须为 RSA2(SHA256) + +```bash +openssl genrsa -out jwt_private_key.pem 1024 +``` + +2. 将私钥转换为 PKCS8 格式 + +```bash +openssl pkcs8 -topk8 -inform PEM -in jwt_private_key.pem -outform PEM -nocrypt -out jwt_private_key_pkcs8.pem +``` + +3. 导出公钥 App Public Key + +```bash +openssl rsa -in jwt_private_key.pem -pubout -out jwt_public_key.pem +``` + +4. 将 jwt_public_key.pem 中的内容,去除换行和空格,转成字符串。 + +处理前: +```language +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBr5wUHXSlLSFU17T4wDX8ehAI +2nnZxCc2SnpgfNwuR3jvViSVyr+Pd6JJEeMcl397qKjWqFD/CRlUSB/UEPQRxxbB +XVlXRB289KE9xteDk04bU17ILgX8Vz/7LFRLn2CpaCSICfWENhoMRJm7xIAodrI3 +FugvRF/6jdTQis2LcQIDAQAB +-----END PUBLIC KEY----- +``` +处理后: +```language +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBr5wUHXSlLSFU17T4wDX8ehAI2nnZxCc2SnpgfNwuR3jvViSVyr+Pd6JJEeMcl397qKjWqFD/CRlUSB/UEPQRxxbBXVlXRB289KE9xteDk04bU17ILgX8Vz/7LFRLn2CpaCSICfWENhoMRJm7xIAodrI3FugvRF/6jdTQis2LcQIDAQAB +-----END PUBLIC KEY----- +``` + +4. 将 jwt_private_key_pkcs8.pem 中的内容,去除换行和空格,转成字符串。 + +处理前: +```language +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMGvnBQddKUtIVTX +tPjANfx6EAjaednEJzZKemB83C5HeO9WJJXKv493okkR4xyXf3uoqNaoUP8JGVRI +H9QQ9BHHFsFdWVdEHbz0oT3G14OTThtTXsguBfxXP/ssVEufYKloJIgJ9YQ2GgxE +mbvEgCh2sjcW6C9EX/qN1NCKzYtxAgMBAAECgYBKBSjq7w7jCUpRuFYrMpnvMV7r +Y0NqG/K4ZuI5+b3T2fC31v4IWQG4fIoCztky1hscUSqlTpIVxY5ujVnMm+YKMXs+ +qW2zyUdvoqUbFNAZstYatg6FQ7QlwXMDnIzlq6w5lEofsO46+0kH/d9IX+cPN0nH +04J1UKwg0ugyjYVUAQJBAP8di+ECIJkVTbi96JWMCfK1eYdxwe+8DEd7kcW2P6qU +/0fxP6qExkbFqPWQbJVNvOKmH5tVW5oi4Q7vaT4MzJECQQDCW4kMG7a6yBKRWZ1/ +hAixqumBv5FFCnL/yzqH6a5n8tb91vcQCwBGfu+YeQt8zVI56BTP4AJDF5KQu1vq +kcDhAkEA+YaHu2QeSDzrEShG5obbcBaKMK1WmEqg5AX8FZrleM5VRqOztvA5Ex3f +3ZgObJZlinYb8g2yE/fLk5UdpgBU0QJAFw+FU0p2g/L5QQXBCkBAR9RfoGV6dxam +TnNunnG7n9nQaI35Ao5LmhG1nAHAuy4hc311+rQ5kHxbh5Czd0GUAQJBALxZpqPZ +y7LrKmTbVLAdd0K1dQ3jWUsqk5HXwlxzrmmypn5ut41zwZQl0znyrv7XcfDZ6dqR +hh20uoiJ/Hfky6A= +-----END PRIVATE KEY----- +``` +处理后: +```language +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMGvnBQddKUtIVTXtPjANfx6EAjaednEJzZKemB83C5HeO9WJJXKv493okkR4xyXf3uoqNaoUP8JGVRIH9QQ9BHHFsFdWVdEHbz0oT3G14OTThtTXsguBfxXP/ssVEufYKloJIgJ9YQ2GgxEmbvEgCh2sjcW6C9EX/qN1NCKzYtxAgMBAAECgYBKBSjq7w7jCUpRuFYrMpnvMV7rY0NqG/K4ZuI5+b3T2fC31v4IWQG4fIoCztky1hscUSqlTpIVxY5ujVnMm+YKMXs+qW2zyUdvoqUbFNAZstYatg6FQ7QlwXMDnIzlq6w5lEofsO46+0kH/d9IX+cPN0nH04J1UKwg0ugyjYVUAQJBAP8di+ECIJkVTbi96JWMCfK1eYdxwe+8DEd7kcW2P6qU/0fxP6qExkbFqPWQbJVNvOKmH5tVW5oi4Q7vaT4MzJECQQDCW4kMG7a6yBKRWZ1/hAixqumBv5FFCnL/yzqH6a5n8tb91vcQCwBGfu+YeQt8zVI56BTP4AJDF5KQu1vqkcDhAkEA+YaHu2QeSDzrEShG5obbcBaKMK1WmEqg5AX8FZrleM5VRqOztvA5Ex3f3ZgObJZlinYb8g2yE/fLk5UdpgBU0QJAFw+FU0p2g/L5QQXBCkBAR9RfoGV6dxamTnNunnG7n9nQaI35Ao5LmhG1nAHAuy4hc311+rQ5kHxbh5Czd0GUAQJBALxZpqPZy7LrKmTbVLAdd0K1dQ3jWUsqk5HXwlxzrmmypn5ut41zwZQl0znyrv7XcfDZ6dqRhh20uoiJ/Hfky6A= +-----END PRIVATE KEY----- +``` + + +5. (可选)将pem内容进行 base64 编码后,配置到k8s + +echo -n '-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDzgNo1jsexpIahW50bbEFcJV6qzOnjjMBum4jMB/CgkJqZHxEh9u1yhdzfdHI+TJREy9RuoqumdRGpVA+YXOwHZnPUU/cHQQkITViPVPSvIHLKA7eqHbmb9FZdQZfFmadBm+AcVpQG+h4SuJgD5yAtye7oRLzxEGXZM+trt8HoFwIDAQAB +-----END PUBLIC KEY-----' |base64 + + +echo -n '-----BEGIN PRIVATE KEY----- +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAPOA2jWOx7GkhqFbnRtsQVwlXqrM6eOMwG6biMwH8KCQmpkfESH27XKF3N90cj5MlETL1G6iq6Z1EalUD5hc7Admc9RT9wdBCQhNWI9U9K8gcsoDt6oduZv0Vl1Bl8WZp0Gb4BxWlAb6HhK4mAPnIC3J7uhEvPEQZdkz62u3wegXAgMBAAECgYEA7mA8veOJsGjs9zd1ZKwki+11cGVrrjxTAbS3RW2cbcNB5RZZslNF/i/3mrUnRb+4AmU8EBalTS4b3RUSs0h8MZV9ObLazZg/c8GlLJeISuRWSuCG7ysvn4NS5ncCj5LW/0w6qKTtzIZqKdMbKfPl1xs+fPCaqlv7mpzIGUYGOKECQQD9125TlH6ftXoR5qaN6CLUuRpdpizjE59pmQMxgL/MQS45G9pUtTHfCZVDKgftqHFZEhL2ysrCbl7TFwHJ2wjHAkEA9ZLqvVPP4RLl78lt/OjLRliGDCeWkw5samzeveIsiaeWItsHzcGqipVw1zCaRRlY/hPs4uHSY0hWWV1+SGr2MQJAcgNdLnU4GovsdDXhAUQOwPUS/pUw/B1IMKnlYUqu2xM7q7Ly8bEg4UjwneY3AWvy3Urc8bRMNeBU/wMKbpvO6QJAVUuZQvdYbdmtidLR5BVLfXyD2rbpYtyQpYp490UWqR1PVX30QPAydv4e+m9ENhnuwhlTnx5Gf/uBGnsRwL9+EQJAcB6ptBg0drWmnpDC3HhFUSWaBVp6BAZic/YeC95pwynlcKScCTI+IY+wXKWRQwcqb2K+STaX4vhsTDLxDZaJAw== +-----END PRIVATE KEY-----' |base64 diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/0.communicate-center-base.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/0.communicate-center-base.yaml new file mode 100644 index 0000000..43fd037 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/0.communicate-center-base.yaml @@ -0,0 +1,17 @@ +# communicate-center-base.yaml + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: communicate-center-test + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/1.communicate-center-env.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/1.communicate-center-env.yaml new file mode 100644 index 0000000..916e977 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/1.communicate-center-env.yaml @@ -0,0 +1,27 @@ +# communicate-center-env.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: communicate-center-test + name: jvm-env +data: + MAX_RAM_PERCENTAGE: "75.0" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: communicate-center-test + name: datasource-env-secret +type: Opaque +data: + # jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/communicate_center?serverTimezone=Asia/Shanghai + JDBC_URL: amRiYzpteXNxbDovL215c3FsLXNlcnZlci5hdXRoeC1zZXJ2aWNlLnN2Yy5jbHVzdGVyLmxvY2FsOjMzMDYvY29tbXVuaWNhdGVfY2VudGVyP3NlcnZlclRpbWV6b25lPUFzaWEvU2hhbmdoYWk= + # communicate_center + JDBC_USERNAME: Y29tbXVuaWNhdGVfY2VudGVy + # 修改为实际的数据库密码,并使用 base64 工具进行编码 + # Nwpu@Supwisdom123 + JDBC_PASSWORD: TndwdUBTdXB3aXNkb20xMjM= + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/2.communicate-center-ingresses.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/2.communicate-center-ingresses.yaml new file mode 100644 index 0000000..13c6006 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/2.communicate-center-ingresses.yaml @@ -0,0 +1,19 @@ +# communicate-center-ingresses.yaml + +# 暂时不使用,直接使用内部地址 +# --- +# apiVersion: extensions/v1beta1 +# kind: Ingress +# metadata: +# namespace: communicate-center-test +# name: communicate-center-api-ingress +# spec: +# rules: +# # 修改为学校的根域名 +# - host: communicate-center-api.paas.xxx.edu.cn +# http: +# paths: +# - path: / +# backend: +# serviceName: communicate-center-poa-svc +# servicePort: http diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/4.0.communicate-center-installer.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/4.0.communicate-center-installer.yaml new file mode 100644 index 0000000..017e5ae --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/4.0.communicate-center-installer.yaml @@ -0,0 +1,46 @@ +# communicate-center-installer.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: communicate-center-test + name: communicate-center-installer-env +data: + DB_TYPE: mysql8 + + +--- +apiVersion: batch/v1 +kind: Job +metadata: + namespace: communicate-center-test + name: communicate-center-installer +spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: communicate-center-installer + spec: + restartPolicy: Never + containers: + - name: communicate-center-installer + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/communicate-center/communicate-center-installer:1.0.0-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: communicate-center-installer-env + resources: + requests: + memory: "256Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/4.1.communicate-center-poa.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/4.1.communicate-center-poa.yaml new file mode 100644 index 0000000..b31bb78 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/8.communicate-center/4.1.communicate-center-poa.yaml @@ -0,0 +1,111 @@ +# communicate-center-poa.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: communicate-center-test + name: communicate-center-poa-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + + USER_DATA_SERVICE_SERVER_URL: http://user-data-service-goa-svc.user-data-service-test.svc.cluster.local:8080 + USER_DATA_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_DATA_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + # 若须对接邮件服务,须提供 SMTP 帐号 + TPAS_MAIL_API_URL: http://agent-service-svc.thirdparty-agent-service-test.svc.cluster.local:8080/api/v1/tpas/mail/console + # 若须对接sms 接口,须进行二开定制 + TPAS_SMS_API_URL: http://agent-service-svc.thirdparty-agent-service-test.svc.cluster.local:8080/api/v1/tpas/sms/console + + TPAS_CLIENT_AUTH_ENABLED: "false" + #TPAS_CLIENT_AUTH_KEY_PASSWORD: "" + #TPAS_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #TPAS_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #TPAS_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #TPAS_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: communicate-center-test + name: communicate-center-poa-svc + labels: + app: communicate-center-poa + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: communicate-center-poa + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: communicate-center-test + name: communicate-center-poa +spec: + selector: + matchLabels: + app: communicate-center-poa + replicas: 1 + template: + metadata: + labels: + app: communicate-center-poa + spec: + containers: + - name: communicate-center-poa + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/communicate-center/communicate-center-poa:1.0.0-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: communicate-center-poa-env + resources: + requests: + memory: "512Mi" + limits: + memory: "512Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/0.jobs-server-base.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/0.jobs-server-base.yaml new file mode 100644 index 0000000..5dc3dda --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/0.jobs-server-base.yaml @@ -0,0 +1,88 @@ +# jobs-server-base.yaml + +#################################################### +# harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: jobs-server-test + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 + + +#################################################### +# rabbitmq-server +#################################################### +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: jobs-server-test + name: rabbitmq-server + labels: + app: rabbitmq + release: rabbitmq-server +type: Opaque +data: + RABBITMQ_USERNAME: Z3Vlc3Q= + RABBITMQ_PASSWORD: Z3Vlc3Q= +--- +apiVersion: v1 +kind: Service +metadata: + namespace: jobs-server-test + name: rabbitmq-server + labels: + app: rabbitmq-server +spec: + ports: + - port: 5672 + targetPort: tcp-1 + protocol: TCP + name: tcp-1 + - port: 15672 + targetPort: tcp-2 + protocol: TCP + name: tcp-2 + selector: + app: rabbitmq-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: jobs-server-test + name: rabbitmq-server +spec: + selector: + matchLabels: + app: rabbitmq-server + replicas: 1 + template: + metadata: + labels: + app: rabbitmq-server + annotations: + sidecar.istio.io/inject: "false" + spec: + containers: + - name: rabbitmq-server + # 若使用了学校搭设的私有仓库,请修改 + image: rabbitmq:management + # 若使用了学校搭设的私有仓库,请修改 为 Always + imagePullPolicy: IfNotPresent + # imagePullPolicy: Always + ports: + - containerPort: 5672 + name: tcp-1 + - containerPort: 15672 + name: tcp-2 + # 若使用了学校搭设的私有仓库,请增加以下配置(取消注释即可) + # imagePullSecrets: + # - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/1.jobs-server-env.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/1.jobs-server-env.yaml new file mode 100644 index 0000000..8a292a7 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/1.jobs-server-env.yaml @@ -0,0 +1,23 @@ +# 1.jobs-server-env.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: jobs-server-test + name: jvm-env +data: + MAX_RAM_PERCENTAGE: "75.0" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: jobs-server-test + name: rabbitmq-env-secret +type: Opaque +data: + SPRING_RABBITMQ_HOST: cmFiYml0bXEtc2VydmVy + SPRING_RABBITMQ_PORT: NTY3Mg== + SPRING_RABBITMQ_USERNAME: Z3Vlc3Q= + SPRING_RABBITMQ_PASSWORD: Z3Vlc3Q= diff --git a/project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/4.1.jobs-server.yaml b/project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/4.1.jobs-server.yaml new file mode 100644 index 0000000..8962a42 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/1.authx-service/9.jobs-server/4.1.jobs-server.yaml @@ -0,0 +1,191 @@ +# 4.1.jobs-server.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: jobs-server-test + name: jobs-server-env +data: + LOGGING_LEVEL_COM_SUPWISDOM_INSITITUTE_JOBS_SERVER: INFO + + +--- +# 组织机构数据,定时触发 OrganizationTrans2UserSvcJob +# 适用于由交换同步到转换表的场景 +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: jobs-server-test + name: jobs-server-organizationtriggertransjob-env +data: + ORGANIZATIONTRIGGERTRANSJOB_ENABLED: "false" + # cron 和 fixedDelay 只能 二选一,配置一个即可 + # 0 0 2 * * * + ORGANIZATIONTRIGGERTRANSJOB_SCHEDULED_CRON: "" + # 120 秒 + ORGANIZATIONTRIGGERTRANSJOB_SCHEDULED_FIXED_DELAY: "1200000" + ORGANIZATIONTRIGGERTRANSJOB_WRITER_DATASOURCE_JDBC_URL: "jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user?serverTimezone=Asia/Shanghai" + ORGANIZATIONTRIGGERTRANSJOB_WRITER_DATASOURCE_USERNAME: "user" + # 修改为实际的数据库密码 + ORGANIZATIONTRIGGERTRANSJOB_WRITER_DATASOURCE_PASSWORD: "Nwpu@Supwisdom123" + + +--- +# 组织机构数据,临时表 - 正式 +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: jobs-server-test + name: jobs-server-organizationtrans2usersvcjob-env +data: + ORGANIZATIONTRANS2USERSVCJOB_ENABLED: "false" + ORGANIZATIONTRANS2USERSVCJOB_PAGE_SIZE: "1000" + ORGANIZATIONTRANS2USERSVCJOB_READER_DATASOURCE_JDBC_URL: "jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user?serverTimezone=Asia/Shanghai" + ORGANIZATIONTRANS2USERSVCJOB_READER_DATASOURCE_USERNAME: "user" + # 修改为实际的数据库密码 + ORGANIZATIONTRANS2USERSVCJOB_READER_DATASOURCE_PASSWORD: "Nwpu@Supwisdom123" + + ORGANIZATIONTRANS2USERSVCJOB_WRITE_USER_DATA_SERVICE_SERVER_URL: http://user-data-service-goa-svc.user-data-service-test.svc.cluster.local:8080 + + +--- +# 帐号数据,定时触发 AccountTrans2UserSvcJob +# 适用于由交换同步到转换表的场景 +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: jobs-server-test + name: jobs-server-accounttriggertransjob-env +data: + ACCOUNTTRIGGERTRANSJOB_ENABLED: "false" + # cron 和 fixedDelay 只能 二选一,配置一个即可 + # 0 0 2 * * * + ACCOUNTTRIGGERTRANSJOB_SCHEDULED_CRON: "" + # 120 秒 + ACCOUNTTRIGGERTRANSJOB_SCHEDULED_FIXED_DELAY: "1200000" + ACCOUNTTRIGGERTRANSJOB_WRITER_DATASOURCE_JDBC_URL: "jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user?serverTimezone=Asia/Shanghai" + ACCOUNTTRIGGERTRANSJOB_WRITER_DATASOURCE_USERNAME: "user" + # 修改为实际的数据库密码 + ACCOUNTTRIGGERTRANSJOB_WRITER_DATASOURCE_PASSWORD: "Nwpu@Supwisdom123" + + +--- +# 帐号数据,临时表 - 正式 +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: jobs-server-test + name: jobs-server-accounttrans2usersvcjob-env +data: + ACCOUNTTRANS2USERSVCJOB_ENABLED: "false" + ACCOUNTTRANS2USERSVCJOB_PAGE_SIZE: "1000" + ACCOUNTTRANS2USERSVCJOB_READER_DATASOURCE_JDBC_URL: "jdbc:mysql://mysql-server.authx-service-test.svc.cluster.local:3306/user?serverTimezone=Asia/Shanghai" + ACCOUNTTRANS2USERSVCJOB_READER_DATASOURCE_USERNAME: "user" + # 修改为实际的数据库密码 + ACCOUNTTRANS2USERSVCJOB_READER_DATASOURCE_PASSWORD: "Nwpu@Supwisdom123" + + ACCOUNTTRANS2USERSVCJOB_WRITE_USER_DATA_SERVICE_SERVER_URL: http://user-data-service-goa-svc.user-data-service-test.svc.cluster.local:8080 + + + +## 须确保 用户服务 将变更数据推送到 rabbit mq 中 + +--- +# 帐号,用户服务 - jobs +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: jobs-server-test + name: jobs-server-accountusersvc2jobsrabbitreceiver-env +data: + ACCOUNTUSERSVC2JOBSRABBITRECEIVER_ENABLED: "false" + ACCOUNTUSERSVC2JOBSRABBITRECEIVER_TRIGGER_EVENTS: "" + # jobs2NwpuOpenldapEventJob + +--- +# 组织机构,用户服务 - jobs +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: jobs-server-test + name: jobs-server-organizationusersvc2jobsrabbitreceiver-env +data: + ORGANIZATIONUSERSVC2JOBSRABBITRECEIVER_ENABLED: "false" + ORGANIZATIONUSERSVC2JOBSRABBITRECEIVER_TRIGGER_EVENTS: "" + # jobs2NwpuOpenldapEventJob + +--- +# 用户组,用户服务 - jobs +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: jobs-server-test + name: jobs-server-groupusersvc2jobsrabbitreceiver-env +data: + GROUPUSERSVC2JOBSRABBITRECEIVER_ENABLED: "false" + GROUPUSERSVC2JOBSRABBITRECEIVER_TRIGGER_EVENTS: "" + # jobs2NwpuOpenldapEventJob + + +--- +# Openldap同步,jobs - openldap +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: jobs-server-test + name: jobs-server-jobs2openldapeventjob-env +data: + JOBS_2_OPENLDAP_EVENT_JOB_ENABLED: "false" + JOBS_2_OPENLDAP_EVENT_JOB_OPENLDAP_LDAP_PROVIDER_URL: ldap://10.40.8.96:389/ + JOBS_2_OPENLDAP_EVENT_JOB_OPENLDAP_LDAP_SECURITY_PRINCIPAL: cn=root,dc=nwpu,dc=edu,dc=cn + JOBS_2_OPENLDAP_EVENT_JOB_OPENLDAP_LDAP_SECURITY_CREDENTIALS: kingstar + + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: jobs-server-test + name: jobs-server +spec: + selector: + matchLabels: + app: jobs-server + replicas: 1 + template: + metadata: + labels: + app: jobs-server + spec: + containers: + - name: jobs-server + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/jobs-server/jobs-server:1.0.0-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: rabbitmq-env-secret + - configMapRef: + name: jobs-server-env + - configMapRef: + name: jobs-server-organizationtriggertransjob-env + - configMapRef: + name: jobs-server-organizationtrans2usersvcjob-env + - configMapRef: + name: jobs-server-accounttriggertransjob-env + - configMapRef: + name: jobs-server-accounttrans2usersvcjob-env + resources: + requests: + memory: "1000Mi" + limits: + memory: "1000Mi" + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/10.0.init.sql b/project/newcapec-test/k8s-rancher/6.admin-platform/10.0.init.sql new file mode 100644 index 0000000..579d3db --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/10.0.init.sql @@ -0,0 +1,73 @@ +-- 10.1.init.sql + +/* +将 paas.example.com 替换为 paas.学校域名.edu.cn +*/ + + +use cas_server; + +-- 更新 服务 admin-center 的信息 + +update TB_SERVICE +set + INFORMATION_URL='http://admin-center.paas.example.com', + LOGOUT_URL='http://admin-center.paas.example.com/cas/slo', + SERVICE_ID='http://admin-center.paas.example.com/cas/(.*)' +where ID='1'; -- todo, modify + +-- 更新 服务 personal-security-center 的信息 + +update TB_SERVICE +set + INFORMATION_URL='http://personal-security-center.paas.example.com', + LOGOUT_URL='http://personal-security-center.paas.example.com/cas/slo', + SERVICE_ID='http://personal-security-center.paas.example.com/cas/(.*)' +where ID='2'; -- todo, modify + +commit; + + +use user_authz; + +-- 更新 admin-center 下的角色同步地址 + +update TB_APPLICATION +set + SYNC_URL='http://admin-center.paas.example.com/api/v1/open/sync/roles' +where ID='1'; -- todo, modify + +commit; + + +use admin_center; + +-- 更新 admin-management 下菜单的访问域 + +update TB_MGT_PERMISSION +set + ORIGIN='http://admin-management.paas.example.com' +where APPLICATION_ID='00000' +; + +commit; + + +-- 更新 admin-platform 下菜单的访问域 + +update TB_MGT_PERMISSION +set + ORIGIN='http://admin-platform.paas.example.com' +where APPLICATION_ID='1' +; + +commit; + +/* +insert into TB_MGT_ROUTE (ID, DELETED, CODE, NAME, STATUS, PATH_PREFIX, URL, STRIP_PREFIX) +values ('23', 0, 'user-biz', '用户服务 - 业务接口', '1', '/api/v1/user/biz', 'http://localhost:8023/api/v1/biz', 1); + +update TB_MGT_ROUTE set URL='http://user-data-service-biz-svc.user-data-service.svc.cluster.local:8080/api/v1/biz' where ID='23'; + +commit; +*/ diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-flow.sql b/project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-flow.sql new file mode 100644 index 0000000..019bfb5 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-flow.sql @@ -0,0 +1,96 @@ +-- 10.1.init.sql + +/* +将 paas.example.com 替换为 paas.学校域名.edu.cn +*/ + +-- 以下脚本为可选操作 + +/* + * 若部署了流程平台、门户的产品 + * 可初始化云平台下的相关菜单数据 + */ + +use admin_center; + +-- flow +-- 如果部署,流程平台,请处理 + +insert into TB_MGT_ROUTE (ID, DELETED, CODE, NAME, STATUS, PATH_PREFIX, URL, STRIP_PREFIX) +values ('50', 0, 'flow-api', '管理门户 - 流程接口', '1', '/api/v1/flow-release', 'http://formflow-formflow-svc.formflow.svc.cluster.local:8080/formflow', 1); + +commit; + +/* +update TB_MGT_ROUTE +set + URL='http://formflow.paas.example.com' +where ID='50'; -- todo, modify + +commit; +*/ + +insert into TB_MGT_ROLE (ID, DELETED, CODE, NAME, MEMO, STATUS) +values ('50', 0, 'flow-admin', '流程表单管理员', '', '1'); +insert into TB_MGT_ROLE (ID, DELETED, CODE, NAME, MEMO, STATUS) +values ('51', 0, 'flow-biz', '流程操作员', '业务、应用组、应用相关管理的操作人员', '1'); + +commit; + + +update TB_MGT_PERMISSION + set LFT = LFT+10 +where LFT>=82 +; + +update TB_MGT_PERMISSION + set RGT = RGT+10 +where RGT>=82 +; + + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('50000', 0, 'formflow-manager', '流程管理', '1', '2', '', '/', '1', '1', 50000, 1, 82, 91); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('50100', 0, 'formflow', '流程表单', '1', '2', 'su-icon-liuchengbiaodan', '/formflow', '1', '50000', 50100, 2, 83, 84); +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('50200', 0, 'workbench', '工作台', '1', '2', 'su-icon-gongzuotai', '/formflow/workbench', '1', '50000', 50200, 2, 85, 86); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('50300', 0, 'instanceManage', '实例管理', '1', '2', 'su-icon-shiliguanli', '/formflow/instanceManage', '1', '50000', 50300, 2, 87, 88); +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('50400', 0, 'agent', '代理代办', '0', '2', 'su-icon-dailidaiban', '/formflow/agent', '1', '50000', 50400, 2, 89, 90); + +commit; + + +insert into TB_MGT_ROLE_PERMISSION (ID, DELETED, ROLE_ID, PERMISSION_ID) + +select CONCAT('1_', ID) as ID, 0 as DELETED, '1' as ROLE_ID, ID as PERMISSION_ID +from TB_MGT_PERMISSION +where (ID like '5____' or ID='1') + and CONCAT('1_', ID) not in (select ID from TB_MGT_ROLE_PERMISSION) +; + +insert into TB_MGT_ROLE_PERMISSION (ID, DELETED, ROLE_ID, PERMISSION_ID) + +select CONCAT('50_', ID) as ID, 0 as DELETED, '50' as ROLE_ID, ID as PERMISSION_ID +from TB_MGT_PERMISSION +where (ID like '5____' or ID='1') + and CONCAT('50_', ID) not in (select ID from TB_MGT_ROLE_PERMISSION) +; + +commit; + + +-- 更新 admin-platform 下菜单的访问域 + +update TB_MGT_PERMISSION +set + ORIGIN='http://admin-platform.paas.example.com' +where LFT >= 82 + and RGT <= 91 +; + +commit; diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-message.sql b/project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-message.sql new file mode 100644 index 0000000..1a03689 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-message.sql @@ -0,0 +1,105 @@ +-- 10.1.init-message.sql + + +/* +将 paas.example.com 替换为 paas.学校域名.edu.cn +*/ + +-- 以下脚本为可选操作 + +/* + * 若部署了流程平台、门户的产品 + * 可初始化云平台下的相关菜单数据 + */ + +use admin_center; + +-- message +-- 如果部署,流程平台,请处理 + + +insert into TB_MGT_ROLE (ID, DELETED, CODE, NAME, MEMO, STATUS) +values ('80', 0, 'message-admin', '消息平台管理员', '', '1'); +insert into TB_MGT_ROLE (ID, DELETED, CODE, NAME, MEMO, STATUS) +values ('81', 0, 'message-opt', '消息平台操作员', '', '1'); + +commit; + + +/* +消息服务 message-backstage +名称 路由 图标 +消息网关管理 /message-backstage/msgGateWay su-icon-xiaoxiwangguan +短信模板管理 /message-backstage/SMSTemplateManage su-icon-mobanguanli +消息类别管理 /message-backstage/msgTypes su-icon-xiaoxileibie +消息任务监控 /message-backstage/msgTaskMonitor su-icon-renwujiankong +消息日志审计 /message-backstage/msgLogAudit su-icon-details +应用管理 /message-backstage/msgSoftManage su-icon-sort +敏感词管理 /message-backstage/SensitiveWords su-icon-lock-w +设置 /message-backstage/msgSendCondition su-icon-print +*/ + +update TB_MGT_PERMISSION + set LFT = LFT+18 +where LFT>=92 +; + +update TB_MGT_PERMISSION + set RGT = RGT+18 +where RGT>=92 +; + + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('80000', 0, 'message-backstage', '消息服务', '1', '2', '', '/', '1', '1', 80000, 1, 92, 109); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('80100', 0, 'formflow', '消息网关管理', '1', '2', 'su-icon-xiaoxiwangguan', '/message-backstage/msgGateWay', '1', '80000', 80100, 2, 93, 94); +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('80200', 0, 'workbench', '短信模板管理', '1', '2', 'su-icon-mobanguanli', '/message-backstage/SMSTemplateManage', '1', '80000', 80200, 2, 95, 96); +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('80300', 0, 'instanceManage', '消息类别管理', '1', '2', 'su-icon-xiaoxileibie', '/message-backstage/msgTypes', '1', '80000', 80300, 2, 97, 98); +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('80400', 0, 'agent', '消息任务监控', '1', '2', 'su-icon-renwujiankong', '/message-backstage/msgTaskMonitor', '1', '80000', 80400, 2, 99, 100); +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('80500', 0, 'agent', '消息日志审计', '1', '2', 'su-icon-details', '/message-backstage/msgLogAudit', '1', '80000', 80500, 2, 101, 102); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('80600', 0, 'agent', '应用管理', '1', '2', 'su-icon-sort', '/message-backstage/msgSoftManage', '1', '80000', 80600, 2, 103, 104); +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('80700', 0, 'agent', '敏感词管理', '1', '2', 'su-icon-lock-w', '/message-backstage/SensitiveWords', '1', '80000', 80700, 2, 105, 106); +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('80800', 0, 'agent', '设置', '1', '2', 'su-icon-print', '/message-backstage/msgSendCondition', '1', '80000', 80800, 2, 107, 108); + +commit; + + +insert into TB_MGT_ROLE_PERMISSION (ID, DELETED, ROLE_ID, PERMISSION_ID) + +select CONCAT('1_', ID) as ID, 0 as DELETED, '1' as ROLE_ID, ID as PERMISSION_ID +from TB_MGT_PERMISSION +where (ID like '8____' or ID='1') + and CONCAT('1_', ID) not in (select ID from TB_MGT_ROLE_PERMISSION) +; + +insert into TB_MGT_ROLE_PERMISSION (ID, DELETED, ROLE_ID, PERMISSION_ID) + +select CONCAT('80_', ID) as ID, 0 as DELETED, '50' as ROLE_ID, ID as PERMISSION_ID +from TB_MGT_PERMISSION +where (ID like '8____' or ID='1') + and CONCAT('80_', ID) not in (select ID from TB_MGT_ROLE_PERMISSION) +; + +commit; + + +-- 更新 admin-platform 下菜单的访问域 + +update TB_MGT_PERMISSION +set + ORIGIN='http://admin-platform.paas.example.com' +where LFT >= 92 + and RGT <= 109 +; + +commit; diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-portal.sql b/project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-portal.sql new file mode 100644 index 0000000..d7357e6 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/10.1.init-portal.sql @@ -0,0 +1,287 @@ +-- 10.1.init.sql + +/* +将 paas.example.com 替换为 paas.学校域名.edu.cn +*/ + +-- 以下脚本为可选操作 + +/* + * 若部署了流程平台、门户的产品 + * 可初始化云平台下的相关菜单数据 + */ + +use admin_center; + +-- portal +-- 如果部署,门户V5,请处理 + +insert into TB_MGT_ROUTE (ID, DELETED, CODE, NAME, STATUS, PATH_PREFIX, URL, STRIP_PREFIX) +values ('60', 0, 'portal-api', '管理门户 - 门户接口', '1', '/api/v1/portal', 'http://ecampus.paas.example.com/', 1); + +commit; + + +update TB_MGT_ROUTE +set + URL='http://ecampus.paas.example.com' +where ID='60'; -- todo, modify + +commit; +/* +http://portal-web.portal.svc.cluster.local:8080/portal-web/api +*/ + + +insert into TB_MGT_ROLE (ID, DELETED, CODE, NAME, MEMO, STATUS) +values ('60', 0, 'portal-admin', '门户管理员', '', '1'); + +commit; + + +/* +update TB_MGT_PERMISSION + set LFT = LFT+10 +where LFT>=89 +; + +update TB_MGT_PERMISSION + set RGT = RGT+10 +where RGT>=89 +; +*/ + + +/* +门户管理 + web端管理 + 系统管理 + 组件模板 + 主题管理 + 主题方案 + 授权管理 + 角色管理 + 服务管理 + 服务管理 + 服务评价管理 + 标签分类管理 + CMS管理 + 幻灯片管理 + 栏目管理 + 内容管理 + 流程管理 + 模板管理 + 滚动公告管理 + 消息管理 + 第三方消息发送设置 + 消息类型管理 + 消息发送详情 +*/ + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('60', 0, 'portal-manage', '门户管理', '1', '1', 'el-icon-s-help', '/', + '60', '0', 60, 1, 93, 136); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6010000', 0, 'web', 'web端管理', + '1', '2', null, null, + '60', '60', 6010000, 1, 94, 105); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6010001', 0, 'web-systemManager', '系统管理', + '1', '2', 'su-icon-xitongguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#web/systemManager/view.html', + '60', '6010000', 6010001, 2, 95, 96); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6010002', 0, 'web-widgetTemplate', '组件模板', + '1', '2', 'su-icon-zujianmoban', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#web/widgetTemplate/view.html', + '60', '6010000', 6010002, 2, 97, 98); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6010003', 0, 'web-themeManager', '主题管理', + '1', '2', 'su-icon-hutiguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#web/themeManager/view.html', + '60', '6010000', 6010003, 2, 99, 100); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6010004', 0, 'web-themeScheme', '主题方案', + '1', '2', 'su-icon-zhutifangan', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#web/themeScheme/view.html', + '60', '6010000', 6010004, 2, 101, 102); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6010005', 0, 'web-oauthManager', 'oauth管理', + '1', '2', 'su-icon-authguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#web/oauthManager/view.html', + '60', '6010000', 6010005, 2, 103, 104); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6020000', 0, 'auth', '授权管理', + '1', '2', null, null, + '60', '60', 6020000, 1, 106, 109); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6020003', 0, 'auth-roleManager', '角色管理', + '1', '2', 'su-icon-jiaoseguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#auth/roleManager/view.html', + '60', '6020000', 6020003, 2, 107, 108); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6030000', 0, 'service', '服务管理', + '1', '2', null, null, + '60', '60', 6030000, 1, 110, 117); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6030001', 0, 'service-appservice', '服务管理', + '1', '2', 'su-icon-fuwuguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#service/appservice/tabs.html', + '60', '6030000', 6030001, 2, 111, 112); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6030002', 0, 'service-evaluate', '服务评价管理', + '1', '2', 'su-icon-fuwupingjiaguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#service/evaluate/form.html', + '60', '6030000', 6030002, 2, 113, 114); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6030003', 0, 'service-tagging', '标签分类管理', + '1', '2', 'su-icon-biaoqianfenleiguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#service/tagging/form.html', + '60', '6030000', 6030003, 2, 115, 116); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6040000', 0, 'cms', 'CMS管理', + '1', '2', null, null, + '60', '60', 6040000, 1, 118, 131); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6040001', 0, 'cms-slide', '幻灯片管理', + '1', '2', 'su-icon-huandengpianguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#cms/slide/list.html', + '60', '6040000', 6040001, 2, 119, 120); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6040002', 0, 'cms-column', '栏目管理', + '1', '2', 'su-icon-lanmuguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#cms/column/list.html', + '60', '6040000', 6040002, 2, 121, 122); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6040003', 0, 'cms-content', '内容管理', + '1', '2', 'su-icon-neirongguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#cms/content/list-manage.html', + '60', '6040000', 6040003, 2, 123, 124); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6040004', 0, 'cms-flow', '流程管理', + '1', '2', 'su-icon-liuchengguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#cms/flow/list.html', + '60', '6040000', 6040004, 2, 125, 126); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6040005', 0, 'cms-template', '模板管理', + '1', '2', 'su-icon-mobanguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#cms/template/list.html', + '60', '6040000', 6040005, 2, 127, 128); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6040006', 0, 'cms-notice', '滚动公告管理', + '1', '2', 'su-icon-gundonggonggaoguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#cms/notice/list.html', + '60', '6040000', 6040006, 2, 129, 130); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6050000', 0, 'message', '消息管理', + '1', '2', null, null, + '60', '60', 6050000, 1, 132, 139); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6050001', 0, 'message-sendsetting', '第三方消息发送设置', + '1', '2', 'su-icon-disanfangxiaoxifasongshezhi', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#message/sendsetting/tabs.html', + '60', '6050000', 6050001, 2, 133, 134); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6050002', 0, 'message-type', '消息类型管理', + '1', '2', 'su-icon-xiaoxileixingguanli', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#message/type/form.html', + '60', '6050000', 6050002, 2, 135, 136); + +insert into TB_MGT_PERMISSION (ID, DELETED, CODE, NAME, + STATUS, TYPE_, ICON, URL, + APPLICATION_ID, PARENT_ID, ORDER_, LEVEL_, LFT, RGT) +values ('6050003', 0, 'message-log', '消息发送详情', + '1', '2', 'su-icon-xiaoxifasongxiangqing', 'http://ecampus.paas.example.com/portal-web/html/admin/index.html#message/sendlog/list.html', + '60', '6050000', 6050003, 2, 137, 138); + + +commit; + + + +insert into TB_MGT_ROLE_PERMISSION (ID, DELETED, ROLE_ID, PERMISSION_ID) + +select CONCAT('1_', ID) as ID, 0 as DELETED, '1' as ROLE_ID, ID as PERMISSION_ID +from TB_MGT_PERMISSION +where ID like '60_____' or ID='60' +; + + + +insert into TB_MGT_ROLE_PERMISSION (ID, DELETED, ROLE_ID, PERMISSION_ID) + +select CONCAT('60_', ID) as ID, 0 as DELETED, '60' as ROLE_ID, ID as PERMISSION_ID +from TB_MGT_PERMISSION +where ID like '60_____' or ID='60' or ID='1' +; + +commit; + + +/* 更新 TB_MGT_PERMISSION 的 ORIGIN */ +/* +select * +from TB_MGT_PERMISSION +where LFT >= (select LFT from TB_MGT_PERMISSION where ID='1') + and RGT <= (select RGT from TB_MGT_PERMISSION where ID='1') +; +*/ + +update TB_MGT_PERMISSION +set + ORIGIN='http://ecampus.paas.example.com' +where APPLICATION_ID = '60' +; + +commit; + diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/0.admin-center-base.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/0.admin-center-base.yaml new file mode 100644 index 0000000..9aeb1f2 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/0.admin-center-base.yaml @@ -0,0 +1,188 @@ +# admin-center-base.yaml + +# 在 rancher 中 命名空间 须手动创建 + +#################################################### +# namespace +#################################################### +apiVersion: v1 +kind: Namespace +metadata: + name: admin-center + # labels: + # istio-injection: enabled + + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + namespace: admin-center + name: harbor-registry +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 + + +#################################################### +# mysql-server +#################################################### +--- +apiVersion: v1 +kind: Service +metadata: + namespace: admin-center + name: mysql-server +spec: + ports: + - name: tcp-mysql + port: 3306 + protocol: TCP + targetPort: 3306 +--- +kind: Endpoints +apiVersion: v1 +metadata: + namespace: admin-center + name: mysql-server +subsets: + - addresses: + # 修改实际MySQL服务器的IP地址 + - ip: 172.30.104.82 + ports: + - name: tcp-mysql + port: 3306 + protocol: TCP + + +#################################################### +# redis-server +#################################################### + +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + app: redis + release: redis-server + name: redis-server + namespace: admin-center +type: Opaque +data: + REDIS_PASSWORD: OEt1d29zbE9pdXc3SA== + +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: redis + release: redis-server + name: redis-server + namespace: admin-center +spec: + ports: + - name: redis + port: 6379 + protocol: TCP + targetPort: redis + selector: + app: redis + release: redis-server + role: master + type: ClusterIP +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: redis + release: redis-server + name: redis-server + namespace: admin-center +spec: + podManagementPolicy: OrderedReady + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: redis + release: redis-server + role: master + serviceName: redis-master + template: + metadata: + labels: + app: redis + release: redis-server + role: master + spec: + containers: + - name: redis-server + env: + - name: REDIS_DISABLE_COMMANDS + value: FLUSHDB,FLUSHALL + - name: REDIS_REPLICATION_MODE + value: master + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-server + key: REDIS_PASSWORD + # 若使用了学校搭设的私有仓库,请修改 + image: bitnami/redis:4.0 + # 若使用了学校搭设的私有仓库,请修改 为 Always + imagePullPolicy: IfNotPresent + # imagePullPolicy: Always + livenessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - containerPort: 6379 + name: redis + protocol: TCP + readinessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 5 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + volumeMounts: + - mountPath: /bitnami/redis/data + name: redis-data + dnsPolicy: ClusterFirst + restartPolicy: Always + securityContext: + fsGroup: 1001 + # runAsUser: 1001 + # https://github.com/bitnami/bitnami-docker-redis/issues/106#issuecomment-388884372 + runAsUser: 0 + terminationGracePeriodSeconds: 30 + volumes: + - emptyDir: {} + name: redis-data + # 若使用了学校搭设的私有仓库,请增加以下配置(取消注释即可) + # imagePullSecrets: + # - name: harbor-registry + updateStrategy: + rollingUpdate: + partition: 0 + type: RollingUpdate + diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/1.admin-center-env.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/1.admin-center-env.yaml new file mode 100644 index 0000000..faaad82 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/1.admin-center-env.yaml @@ -0,0 +1,39 @@ +# admin-center-env.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: admin-center + name: jvm-env +data: + MAX_RAM_PERCENTAGE: "75.0" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: admin-center + name: datasource-env-secret +type: Opaque +data: + # jdbc:mysql://mysql-server:3306/admin_center?serverTimezone=Asia/Shanghai + JDBC_URL: amRiYzpteXNxbDovL215c3FsLXNlcnZlcjozMzA2L2FkbWluX2NlbnRlcj9zZXJ2ZXJUaW1lem9uZT1Bc2lhL1NoYW5naGFp + # admin_center + JDBC_USERNAME: YWRtaW5fY2VudGVy + # 修改为实际的数据库密码,并使用 base64 工具进行编码 + # kingstar + JDBC_PASSWORD: a2luZ3N0YXI= + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: admin-center + name: redis-env-secret +type: Opaque +data: + SPRING_REDIS_HOST: cmVkaXMtc2VydmVy + SPRING_REDIS_PORT: NjM3OQ== + SPRING_REDIS_PASSWORD: OEt1d29zbE9pdXc3SA== + diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/2.admin-center-ingresses.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/2.admin-center-ingresses.yaml new file mode 100644 index 0000000..ec07477 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/2.admin-center-ingresses.yaml @@ -0,0 +1,62 @@ +# admin-center-ingresses.yaml + + +# 云平台管理后端接口 +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + namespace: admin-center + name: admin-center-ingress + annotations: + nginx.ingress.kubernetes.io/proxy-buffer-size: "8k" +spec: + rules: + # 修改为学校的根域名 + - host: admin-center.paas.xxx.edu.cn + http: + paths: + - path: / + backend: + serviceName: admin-center-zuul-svc + servicePort: http + + +# 云平台菜单开放接口 +# 暂时不使用,直接使用内部地址 +# --- +# apiVersion: extensions/v1beta1 +# kind: Ingress +# metadata: +# namespace: admin-center +# name: admin-center-api-ingress +# spec: +# rules: +# # 修改为学校的根域名 +# - host: admin-center-api.paas.xxx.edu.cn +# http: +# paths: +# - path: / +# backend: +# serviceName: admin-center-poa-svc +# servicePort: http + + +# 云平台管理前端 +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + namespace: admin-center + name: admin-center-management-ingress +spec: + rules: + # 修改为学校的根域名 + - host: admin-management.paas.xxx.edu.cn + http: + paths: + - path: / + backend: + serviceName: admin-center-management-svc + servicePort: http + diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.0.admin-center-sa-installer.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.0.admin-center-sa-installer.yaml new file mode 100644 index 0000000..7f456ce --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.0.admin-center-sa-installer.yaml @@ -0,0 +1,47 @@ +# admin-center-sa-installer.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: admin-center + name: admin-center-sa-installer-env +data: + DB_TYPE: mysql8 + + +--- +apiVersion: batch/v1 +kind: Job +metadata: + namespace: admin-center + name: admin-center-sa-installer +spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: admin-center-sa-installer + spec: + restartPolicy: Never + containers: + - name: admin-center-sa-installer + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/admin-center/admin-center-sa-installer:1.0.0-SNAPSHOT + imagePullPolicy: Always + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - configMapRef: + name: admin-center-sa-installer-env + resources: + requests: + memory: "256Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.1.admin-center-poa.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.1.admin-center-poa.yaml new file mode 100644 index 0000000..1534603 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.1.admin-center-poa.yaml @@ -0,0 +1,117 @@ +# admin-center-poa.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: admin-center + name: admin-center-poa-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + LOGGING_LEVEL_COM_SUPWISDOM_INSTITUTE_ADMIN_CENTER_POA: INFO + + + ADMIN_CENTER_SA_SERVER_URL: http://admin-center-sa-svc.admin-center.svc.cluster.local:8080 + ADMIN_CENTER_SA_CLIENT_AUTH_ENABLED: "false" + #ADMIN_CENTER_SA_CLIENT_AUTH_KEY_PASSWORD: "" + #ADMIN_CENTER_SA_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #ADMIN_CENTER_SA_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #ADMIN_CENTER_SA_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #ADMIN_CENTER_SA_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + USER_DATA_SERVICE_SERVER_URL: http://user-data-service-goa-svc.user-data-service.svc.cluster.local:8080 + USER_DATA_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_DATA_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + USER_AUTHZ_SERVICE_SERVER_URL: http://user-authorization-sa-svc.user-authorization-service.svc.cluster.local:8080 + USER_AUTHZ_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #USER_AUTHZ_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: admin-center + name: admin-center-poa-svc + labels: + app: admin-center-poa + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: admin-center-poa + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: admin-center + name: admin-center-poa +spec: + selector: + matchLabels: + app: admin-center-poa + replicas: 1 + template: + metadata: + labels: + app: admin-center-poa + spec: + containers: + - name: admin-center-poa + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/admin-center/admin-center-poa:1.0.2-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: redis-env-secret + - configMapRef: + name: admin-center-poa-env + resources: + requests: + memory: "400Mi" + limits: + memory: "400Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.2.admin-center-sa.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.2.admin-center-sa.yaml new file mode 100644 index 0000000..d7c8aee --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.2.admin-center-sa.yaml @@ -0,0 +1,101 @@ +# admin-center-sa.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: admin-center + name: admin-center-sa-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + + SERVER_MAXHTTPHEADERSIZE: "10240" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: admin-center + name: admin-center-sa-env-secret +type: Opaque +data: + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_PASSWORD: "" + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: admin-center + name: admin-center-sa-svc + labels: + app: admin-center-sa + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: admin-center-sa +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: admin-center + name: admin-center-sa +spec: + selector: + matchLabels: + app: admin-center-sa + replicas: 1 + template: + metadata: + labels: + app: admin-center-sa + spec: + containers: + - name: admin-center-sa + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/admin-center/admin-center-sa:1.0.0-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: datasource-env-secret + - secretRef: + name: admin-center-sa-env-secret + - configMapRef: + name: admin-center-sa-env + resources: + requests: + memory: "400Mi" + limits: + memory: "400Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.4.admin-center-bff.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.4.admin-center-bff.yaml new file mode 100644 index 0000000..f03a397 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.4.admin-center-bff.yaml @@ -0,0 +1,143 @@ +# admin-center-bff.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: admin-center + name: admin-center-bff-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + LOGGING_LEVEL_COM_SUPWISDOM_INSTITUTE_ADMIN_CENTER_BFF: INFO + + + ADMIN_CENTER_SA_SERVER_URL: http://admin-center-sa-svc.admin-center.svc.cluster.local:8080 + ADMIN_CENTER_SA_CLIENT_AUTH_ENABLED: "false" + #ADMIN_CENTER_SA_CLIENT_AUTH_KEY_PASSWORD: "" + #ADMIN_CENTER_SA_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #ADMIN_CENTER_SA_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #ADMIN_CENTER_SA_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #ADMIN_CENTER_SA_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + CASSERVER_SA_API_SERVER_URL: http://cas-server-sa-api-svc.cas-server.svc.cluster.local:8080 + CASSERVER_SA_API_CLIENT_AUTH_ENABLED: "false" + #CASSERVER_SA_API_CLIENT_AUTH_KEY_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #CASSERVER_SA_API_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #CASSERVER_SA_API_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + USER_DATA_SERVICE_SERVER_URL: http://user-data-service-goa-svc.user-data-service.svc.cluster.local:8080 + USER_DATA_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_DATA_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + USER_AUTHZ_SERVICE_SERVER_URL: http://user-authorization-sa-svc.user-authorization-service.svc.cluster.local:8080 + USER_AUTHZ_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #USER_AUTHZ_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + # PERSONAL_SECURITY_CENTER_SERVER_URL: http://personal-security-center-sa-api-svc.personal-security-center.svc.cluster.local:8080 + # PERSONAL_SECURITY_CENTER_CLIENT_AUTH_ENABLED: "false" + #PERSONAL_SECURITY_CENTER_CLIENT_AUTH_KEY_PASSWORD: "" + #PERSONAL_SECURITY_CENTER_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #PERSONAL_SECURITY_CENTER_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #PERSONAL_SECURITY_CENTER_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #PERSONAL_SECURITY_CENTER_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + + TPAS_FILE_API_URL: http://agent-service-svc.thirdparty-agent-service.svc.cluster.local:8080/api/v1/tpas/file/db + TPAS_CLIENT_AUTH_ENABLED: "false" + #TPAS_CLIENT_AUTH_KEY_PASSWORD: "" + #TPAS_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/client/client.keystore + #TPAS_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #TPAS_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/client/client.truststore + #TPAS_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: admin-center + name: admin-center-bff-svc + labels: + app: admin-center-bff + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: admin-center-bff + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: admin-center + name: admin-center-bff +spec: + selector: + matchLabels: + app: admin-center-bff + replicas: 1 + template: + metadata: + labels: + app: admin-center-bff + spec: + containers: + - name: admin-center-bff + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/admin-center/admin-center-bff:1.0.2-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: redis-env-secret + - configMapRef: + name: admin-center-bff-env + resources: + requests: + memory: "400Mi" + limits: + memory: "400Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.5.admin-center-zuul.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.5.admin-center-zuul.yaml new file mode 100644 index 0000000..71ed6d3 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.5.admin-center-zuul.yaml @@ -0,0 +1,170 @@ +# admin-center-zuul.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: admin-center + name: admin-center-zuul-env +data: + SERVER_PORT: "8080" + SSL_ENABLED: "false" + #SSL_KEYSTORE_FILE: file:/certs/server/server.keystore + #SSL_KEYSTORE_PASSWORD: "" + #SSL_TRUSTSTORE_FILE: file:/certs/server/server.truststore + #SSL_TRUSTSTORE_PASSWORD: "" + + SERVER_MAXHTTPHEADERSIZE: "10240" + + # SERVER_TOMCAT_MAX_CONNECTIONS: "10000" + # SERVER_TOMCAT_ACCEPT_COUNT: "5000" + # SERVER_TOMCAT_MAX_THREADS: "800" + # SERVER_TOMCAT_MIN_SPARE_THREADS: "100" + + # SPRING_REDIS_JEDIS_POOL_MAXACTIVE: "800" + + + ZUUL_HOST_MAX_PER_ROUTE_CONNECTIONS: "1000" + ZUUL_HOST_MAX_TOTAL_CONNECTIONS: "1000" + + ZUUL_SEMAPHORE_MAX_SEMAPHORES: "10000" + + + INFRAS_SECURITY_BASIC_ENABLED: "false" + + INFRAS_SECURITY_JWT_ENABLED: "true" + #INFRAS_SECURITY_JWT_KEY_ALIAS: "supwisdom-jwt-key" + #INFRAS_SECURITY_JWT_KEY_PASSWORD: "changeit" + #INFRAS_SECURITY_JWT_KEY_STORE: "file:/certs/jwt/jwt.keystore" + #INFRAS_SECURITY_JWT_KEY_STORE_PASSWORD: "changeit" + + INFRAS_SECURITY_JWT_TOKEN_GENERATE_TYPE: cas + INFRAS_SECURITY_JWT_TOKEN_DECRYPT_KEY_PRIVATE_KEY_PEM_PKCS8: "" + INFRAS_SECURITY_JWT_TOKEN_SIGNING_KEY_URL: "http://cas-server-site-webapp-svc.cas-server.svc.cluster.local:8080/cas/jwt/publicKey" + + + INFRAS_SECURITY_CAS_ENABLED: "true" + # 修改为学校的admin-center的访问域名 + APP_SERVER_HOST_URL: "http://admin-center.paas.xxx.edu.cn" + #APP_LOGIN_URL: "/cas/login" + #APP_LOGOUT_URL: "/cas/logout" + # 修改为学校的cas的访问域名 + CAS_SERVER_HOST_URL: "http://cas.paas.xxx.edu.cn/cas" + + + ZUUL_HTTPCLIENT_CLIENT_AUTH_ENABLED: "false" + #ZUUL_HTTPCLIENT_CLIENT_AUTH_KEY_PASSWORD: "" + #ZUUL_HTTPCLIENT_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #ZUUL_HTTPCLIENT_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + + ADMIN_CENTER_SA_SERVER_URL: http://admin-center-sa-svc.admin-center.svc.cluster.local:8080 + ADMIN_CENTER_SA_CLIENT_AUTH_ENABLED: "false" + #ADMIN_CENTER_SA_CLIENT_AUTH_KEY_PASSWORD: "" + #ADMIN_CENTER_SA_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #ADMIN_CENTER_SA_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #ADMIN_CENTER_SA_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #ADMIN_CENTER_SA_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + USER_DATA_SERVICE_SERVER_URL: http://user-data-service-goa-svc.user-data-service.svc.cluster.local:8080 + USER_DATA_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_DATA_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #USER_DATA_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #USER_DATA_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + + USER_AUTHZ_SERVICE_SERVER_URL: http://user-authorization-sa-svc.user-authorization-service.svc.cluster.local:8080 + USER_AUTHZ_SERVICE_CLIENT_AUTH_ENABLED: "false" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEY_PASSWORD: "" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEYSTORE_FILE: file:/certs/common/common.keystore + #USER_AUTHZ_SERVICE_CLIENT_AUTH_KEYSTORE_PASSWORD: "" + #USER_AUTHZ_SERVICE_CLIENT_AUTH_TRUSTSTORE_FILE: file:/certs/common/common.truststore + #USER_AUTHZ_SERVICE_CLIENT_AUTH_TRUSTSTORE_PASSWORD: "" + +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: admin-center + name: admin-center-zuul-env-secret +type: Opaque +data: + # 参考 certs/jwt/readme.md 生成公私钥pem,替换相关配置 + INFRAS_SECURITY_JWT_PUBLIC_KEY_PEM: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTRHTkFEQ0JpUUtCZ1FDcWUzYUpRVm1VNWY1VDhIdU1PcEloMjhrZQpNU3hpUkh2NXNNa29iVGd5T3VRaVVYVEJLS3JwUjVNUWFiaERFZG1WSHlVWFowUFRLRHJCYk9rWkVwTVRmbXBHCnBibE5hOHJkS0RRZG5MYVFLNHBkKzN1clJSdDQzYXhISTdQZHdnRmx3ZThybmYvZllVK3lpcWhDaFBjbkdSNXAKUE9hOE4xZFkzQXlwWWhZa2dRSURBUUFCCi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ== + INFRAS_SECURITY_JWT_PRIVATE_KEY_PEM_PKCS8: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUNlQUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQW1Jd2dnSmVBZ0VBQW9HQkFLcDdkb2xCV1pUbC9sUHcKZTR3NmtpSGJ5UjR4TEdKRWUvbXd5U2h0T0RJNjVDSlJkTUVvcXVsSGt4QnB1RU1SMlpVZkpSZG5ROU1vT3NGcwo2UmtTa3hOK2FrYWx1VTFyeXQwb05CMmN0cEFyaWwzN2U2dEZHM2pkckVjanM5M0NBV1hCN3l1ZC85OWhUN0tLCnFFS0U5eWNaSG1rODVydzNWMWpjREtsaUZpU0JBZ01CQUFFQ2dZRUFuNXN2QXBrMzhQclIvR3ZzZndCbXgyUXAKQ2ljblVtaWpXTVIxejI5UmFWVlJOLy9pdXVRRC9wcVB5Skh4ZkhrOXB5cWRZeWUraS9YaDdDeTJuazZSZWVyMAowcG5lbUFJNFpNVnFaWW8rUHFIdU1ZSnRjS1ZpSHRLUElVZFVEaGpleE1iVjhPdXdFRjdDNERsNXhveXV6cUZvClZzRTFlaVNpVERmQWNUcmc4SEVDUVFEYjVrZU5FUUxtMEFPK0I3TDZvUi9URExHODZiaXU1Szc0VEVzMmphM0gKQ0JBa1FLUXJvMWwxS3c2Y1ZKcXlGR09SMEI1ZG9Mc2V2cVNTWVV5KytrZGpBa0VBeG5oUzh5SnF1Z3ordFV2ZApKMW1sSm9UbTFxNjFHNDBzTFhMY1RtU3F1a2dyTDBDMm1ycXJGQUF4MjF2ek83azF0NU44aEZUY1VnR3BMa015CjNiOGp5d0pBWEFBVk1XekxsUHUwaFIyOWdPUkdaMHNwVll0SFRFeTY4NEVmK3B2OTk0WmxFblhFK2NqbTFZR0YKSkZ5MU9Bb1Z1bHlqUjdMR2RzOTJGUlFHUXVSOVZ3SkJBS1JNUlhicS9la3BDczR3a0ZLYi9vQ2xzcWIwR0E5SAp6ZE9ONjF5bUwwTm9yUDlBRmlwKzcxTHVXbGVhaGYvaDhkc1hxQk93WUhjdTBzdnVhelJ3b0FNQ1FRQ05yM0FrCkZ6aUZBZGQvWkFmaFhpSURHemo1dlRCRkpaQ01TR1hXbVBJcTdnWEN0RUM4Y2VvRHhOY0JLRGtxeEQvaGJVcmwKZStmeDdqeE9kUXhwQkF1RQotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0t + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: admin-center + name: admin-center-zuul-svc + labels: + app: admin-center-zuul + needMonitor: 'true' +spec: + ports: + - port: 8080 + targetPort: http + protocol: TCP + name: http + - port: 6060 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + app: admin-center-zuul + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: admin-center + name: admin-center-zuul +spec: + selector: + matchLabels: + app: admin-center-zuul + replicas: 1 + template: + metadata: + labels: + app: admin-center-zuul + spec: + containers: + - name: admin-center-zuul + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/admin-center/admin-center-zuul:1.0.2-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 8080 + name: http + - containerPort: 6060 + name: http-metrics + envFrom: + - configMapRef: + name: jvm-env + - secretRef: + name: redis-env-secret + - secretRef: + name: admin-center-zuul-env-secret + - configMapRef: + name: admin-center-zuul-env + resources: + requests: + memory: "400Mi" + limits: + memory: "400Mi" + readinessProbe: + httpGet: + path: /actuator/health + port: 8080 + initialDelaySeconds: 20 + periodSeconds: 5 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 10 + imagePullSecrets: + - name: harbor-registry + diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.9.admin-center-management.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.9.admin-center-management.yaml new file mode 100644 index 0000000..4684a8c --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/4.9.admin-center-management.yaml @@ -0,0 +1,69 @@ +# 4.9.admin-center-management.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: admin-center + name: admin-center-management-env +data: + SCHOOL_NAME: "none" + # 修改为学校的 admin-center 的访问域名 + AUTH_URL: http://admin-center.paas.xxx.edu.cn/jwt/cas + # 修改为学校的 admin-center 的访问域名 + BACKEND_URL: http://admin-center.paas.xxx.edu.cn + # 修改为学校的 admin-management 的访问域名 + SERVER_URL: http://admin-management.paas.xxx.edu.cn + + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: admin-center + name: admin-center-management-svc + labels: + app: admin-center-management-svc +spec: + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: admin-center-management + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: admin-center + name: admin-center-management +spec: + selector: + matchLabels: + app: admin-center-management + replicas: 1 + template: + metadata: + labels: + app: admin-center-management + spec: + containers: + - name: admin-center-management + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/admin-center/admin-center-management:0.0.1-SNAPSHOT + imagePullPolicy: Always + ports: + - containerPort: 80 + name: http + envFrom: + - configMapRef: + name: admin-center-management-env + resources: + requests: + memory: "128Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/certs/jwt/readme.md b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/certs/jwt/readme.md new file mode 100644 index 0000000..5ea3539 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/6.admin-center/certs/jwt/readme.md @@ -0,0 +1,83 @@ +# readme.md + + +## 使用 openssl 生成 公私钥 + + +1. 生成私钥 App Private Key + +必须为 RSA2(SHA256) + +```bash +openssl genrsa -out jwt_private_key.pem 1024 +``` + +2. 将私钥转换为 PKCS8 格式 + +```bash +openssl pkcs8 -topk8 -inform PEM -in jwt_private_key.pem -outform PEM -nocrypt -out jwt_private_key_pkcs8.pem +``` + +3. 导出公钥 App Public Key + +```bash +openssl rsa -in jwt_private_key.pem -pubout -out jwt_public_key.pem +``` + +4. 将 jwt_public_key.pem 中的内容,去除换行和空格,转成字符串。 + +处理前: +```language +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBr5wUHXSlLSFU17T4wDX8ehAI +2nnZxCc2SnpgfNwuR3jvViSVyr+Pd6JJEeMcl397qKjWqFD/CRlUSB/UEPQRxxbB +XVlXRB289KE9xteDk04bU17ILgX8Vz/7LFRLn2CpaCSICfWENhoMRJm7xIAodrI3 +FugvRF/6jdTQis2LcQIDAQAB +-----END PUBLIC KEY----- +``` +处理后: +```language +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBr5wUHXSlLSFU17T4wDX8ehAI2nnZxCc2SnpgfNwuR3jvViSVyr+Pd6JJEeMcl397qKjWqFD/CRlUSB/UEPQRxxbBXVlXRB289KE9xteDk04bU17ILgX8Vz/7LFRLn2CpaCSICfWENhoMRJm7xIAodrI3FugvRF/6jdTQis2LcQIDAQAB +-----END PUBLIC KEY----- +``` + +4. 将 jwt_private_key_pkcs8.pem 中的内容,去除换行和空格,转成字符串。 + +处理前: +```language +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMGvnBQddKUtIVTX +tPjANfx6EAjaednEJzZKemB83C5HeO9WJJXKv493okkR4xyXf3uoqNaoUP8JGVRI +H9QQ9BHHFsFdWVdEHbz0oT3G14OTThtTXsguBfxXP/ssVEufYKloJIgJ9YQ2GgxE +mbvEgCh2sjcW6C9EX/qN1NCKzYtxAgMBAAECgYBKBSjq7w7jCUpRuFYrMpnvMV7r +Y0NqG/K4ZuI5+b3T2fC31v4IWQG4fIoCztky1hscUSqlTpIVxY5ujVnMm+YKMXs+ +qW2zyUdvoqUbFNAZstYatg6FQ7QlwXMDnIzlq6w5lEofsO46+0kH/d9IX+cPN0nH +04J1UKwg0ugyjYVUAQJBAP8di+ECIJkVTbi96JWMCfK1eYdxwe+8DEd7kcW2P6qU +/0fxP6qExkbFqPWQbJVNvOKmH5tVW5oi4Q7vaT4MzJECQQDCW4kMG7a6yBKRWZ1/ +hAixqumBv5FFCnL/yzqH6a5n8tb91vcQCwBGfu+YeQt8zVI56BTP4AJDF5KQu1vq +kcDhAkEA+YaHu2QeSDzrEShG5obbcBaKMK1WmEqg5AX8FZrleM5VRqOztvA5Ex3f +3ZgObJZlinYb8g2yE/fLk5UdpgBU0QJAFw+FU0p2g/L5QQXBCkBAR9RfoGV6dxam +TnNunnG7n9nQaI35Ao5LmhG1nAHAuy4hc311+rQ5kHxbh5Czd0GUAQJBALxZpqPZ +y7LrKmTbVLAdd0K1dQ3jWUsqk5HXwlxzrmmypn5ut41zwZQl0znyrv7XcfDZ6dqR +hh20uoiJ/Hfky6A= +-----END PRIVATE KEY----- +``` +处理后: +```language +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMGvnBQddKUtIVTXtPjANfx6EAjaednEJzZKemB83C5HeO9WJJXKv493okkR4xyXf3uoqNaoUP8JGVRIH9QQ9BHHFsFdWVdEHbz0oT3G14OTThtTXsguBfxXP/ssVEufYKloJIgJ9YQ2GgxEmbvEgCh2sjcW6C9EX/qN1NCKzYtxAgMBAAECgYBKBSjq7w7jCUpRuFYrMpnvMV7rY0NqG/K4ZuI5+b3T2fC31v4IWQG4fIoCztky1hscUSqlTpIVxY5ujVnMm+YKMXs+qW2zyUdvoqUbFNAZstYatg6FQ7QlwXMDnIzlq6w5lEofsO46+0kH/d9IX+cPN0nH04J1UKwg0ugyjYVUAQJBAP8di+ECIJkVTbi96JWMCfK1eYdxwe+8DEd7kcW2P6qU/0fxP6qExkbFqPWQbJVNvOKmH5tVW5oi4Q7vaT4MzJECQQDCW4kMG7a6yBKRWZ1/hAixqumBv5FFCnL/yzqH6a5n8tb91vcQCwBGfu+YeQt8zVI56BTP4AJDF5KQu1vqkcDhAkEA+YaHu2QeSDzrEShG5obbcBaKMK1WmEqg5AX8FZrleM5VRqOztvA5Ex3f3ZgObJZlinYb8g2yE/fLk5UdpgBU0QJAFw+FU0p2g/L5QQXBCkBAR9RfoGV6dxamTnNunnG7n9nQaI35Ao5LmhG1nAHAuy4hc311+rQ5kHxbh5Czd0GUAQJBALxZpqPZy7LrKmTbVLAdd0K1dQ3jWUsqk5HXwlxzrmmypn5ut41zwZQl0znyrv7XcfDZ6dqRhh20uoiJ/Hfky6A= +-----END PRIVATE KEY----- +``` + + +5. (可选)将pem内容进行 base64 编码后,配置到k8s + +echo -n '-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBr5wUHXSlLSFU17T4wDX8ehAI2nnZxCc2SnpgfNwuR3jvViSVyr+Pd6JJEeMcl397qKjWqFD/CRlUSB/UEPQRxxbBXVlXRB289KE9xteDk04bU17ILgX8Vz/7LFRLn2CpaCSICfWENhoMRJm7xIAodrI3FugvRF/6jdTQis2LcQIDAQAB +-----END PUBLIC KEY-----' |base64 + + +echo -n '-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMGvnBQddKUtIVTXtPjANfx6EAjaednEJzZKemB83C5HeO9WJJXKv493okkR4xyXf3uoqNaoUP8JGVRIH9QQ9BHHFsFdWVdEHbz0oT3G14OTThtTXsguBfxXP/ssVEufYKloJIgJ9YQ2GgxEmbvEgCh2sjcW6C9EX/qN1NCKzYtxAgMBAAECgYBKBSjq7w7jCUpRuFYrMpnvMV7rY0NqG/K4ZuI5+b3T2fC31v4IWQG4fIoCztky1hscUSqlTpIVxY5ujVnMm+YKMXs+qW2zyUdvoqUbFNAZstYatg6FQ7QlwXMDnIzlq6w5lEofsO46+0kH/d9IX+cPN0nH04J1UKwg0ugyjYVUAQJBAP8di+ECIJkVTbi96JWMCfK1eYdxwe+8DEd7kcW2P6qU/0fxP6qExkbFqPWQbJVNvOKmH5tVW5oi4Q7vaT4MzJECQQDCW4kMG7a6yBKRWZ1/hAixqumBv5FFCnL/yzqH6a5n8tb91vcQCwBGfu+YeQt8zVI56BTP4AJDF5KQu1vqkcDhAkEA+YaHu2QeSDzrEShG5obbcBaKMK1WmEqg5AX8FZrleM5VRqOztvA5Ex3f3ZgObJZlinYb8g2yE/fLk5UdpgBU0QJAFw+FU0p2g/L5QQXBCkBAR9RfoGV6dxamTnNunnG7n9nQaI35Ao5LmhG1nAHAuy4hc311+rQ5kHxbh5Czd0GUAQJBALxZpqPZy7LrKmTbVLAdd0K1dQ3jWUsqk5HXwlxzrmmypn5ut41zwZQl0znyrv7XcfDZ6dqRhh20uoiJ/Hfky6A= +-----END PRIVATE KEY-----' |base64 diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/0.admin-platform-base.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/0.admin-platform-base.yaml new file mode 100644 index 0000000..3777c8e --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/0.admin-platform-base.yaml @@ -0,0 +1,29 @@ +# 0.admin-platform-base.yaml + +# 在 rancher 中 命名空间 须手动创建 + +#################################################### +# namespace +#################################################### +apiVersion: v1 +kind: Namespace +metadata: + name: admin-platform + # labels: + # istio-injection: enabled + + +#################################################### +# supwisdom harbor private docker registry +#################################################### +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/dockerconfigjson +metadata: + name: harbor-registry + namespace: admin-platform +data: + # 修改harbor仓库配置,并使用 base64 工具进行编码 + # {"auths":{"harbor.supwisdom.com":{"password":"PWMgP85qiLFC","username":"rancher.devops"}}} + .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3Iuc3Vwd2lzZG9tLmNvbSI6eyJwYXNzd29yZCI6IlBXTWdQODVxaUxGQyIsInVzZXJuYW1lIjoicmFuY2hlci5kZXZvcHMifX19 diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/2.admin-platform-ingresses.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/2.admin-platform-ingresses.yaml new file mode 100644 index 0000000..f8c644b --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/2.admin-platform-ingresses.yaml @@ -0,0 +1,36 @@ +# 2.admin-platform-ingresses.yaml + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: admin-platform-ingress + namespace: admin-platform +spec: + rules: + # 修改为学校的根域名 + - host: admin-platform.paas.xxx.edu.cn + http: + paths: + - path: / + backend: + serviceName: admin-platform-svc + servicePort: http + + +# --- +# apiVersion: extensions/v1beta1 +# kind: Ingress +# metadata: +# name: personal-center-ingress +# namespace: admin-platform +# spec: +# rules: +# # 修改为学校的根域名 +# - host: personal-center.paas.supwisdom.com +# http: +# paths: +# - path: / +# backend: +# serviceName: personal-center-svc +# servicePort: http diff --git a/project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/4.2.admin-platform.yaml b/project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/4.2.admin-platform.yaml new file mode 100644 index 0000000..c0f91f4 --- /dev/null +++ b/project/newcapec-test/k8s-rancher/6.admin-platform/7.admin-platform/4.2.admin-platform.yaml @@ -0,0 +1,74 @@ +# 04-2-admin-platform.yaml + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: admin-platform + name: admin-platform-env +data: + # 修改为学校的 admin-platform 的访问域名 + LAYOUT_SPA_URL: http://admin-platform.paas.xxx.edu.cn/layout + CAS_SERVER_SPA_URL: http://admin-platform.paas.xxx.edu.cn/cas-server + USER_SERVER_SPA_URL: http://admin-platform.paas.xxx.edu.cn/user-server + AUTH_SERVER_SPA_URL: http://admin-platform.paas.xxx.edu.cn/auth-server + ACCOUNT_CENTER_SPA_URL: http://admin-platform.paas.xxx.edu.cn/account-center + FORM_FLOW_SPA_URL: http://admin-platform.paas.xxx.edu.cn/form-flow + + SCHOOL_NAME: "none" + MAIN_SERVER: http://admin-platform.paas.xxx.edu.cn + + # 修改为学校的访问域名 + SERVER_CONFIG: '{"ROOT": "http://admin-platform.paas.xxx.edu.cn/","AUTH": "http://admin-center.paas.xxx.edu.cn/jwt/cas","BASE_BACK_API": "http://admin-center.paas.xxx.edu.cn/","AUTH_PERSONAL": "http://admin-center.paas.xxx.edu.cn/jwt/cas","PERSONAL_CENTER_API": "http://admin-center.paas.xxx.edu.cn/","PERSONAL_CENTER": "http://admin-platform.paas.xxx.edu.cn/personal-center/","AUTH_FORMFLOW": "http://formflow.paas.xxx.edu.cn/release/cas/authen/redirect","FORM_DESIGN": "http://formflow.paas.xxx.edu.cn/form-design","FORM_DESIGN_PORTAL": "http://formflow.paas.xxx.edu.cn/form-design-portal","FORM_FILE": "http://formflow.paas.xxx.edu.cn/form-file","PERSONAL_CENTER_API_L": "http://portal.paas.xxx.edu.cn/portal-web/","PERSONAL_CENTER_IMAGE_API": "http://portal.paas.xxx.edu.cn/resources/",}' + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: admin-platform + name: admin-platform-svc + labels: + app: admin-platform-svc +spec: + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: admin-platform + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: admin-platform + name: admin-platform +spec: + selector: + matchLabels: + app: admin-platform + replicas: 1 + template: + metadata: + labels: + app: admin-platform + spec: + containers: + - name: admin-platform + # 若使用了学校搭设的私有仓库,请修改 + image: harbor.supwisdom.com/admin-platform/admin-platform:1.0.0 + imagePullPolicy: Always + ports: + - containerPort: 80 + name: http + envFrom: + - configMapRef: + name: admin-platform-env + resources: + requests: + memory: "128Mi" + limits: + memory: "256Mi" + imagePullSecrets: + - name: harbor-registry -- 2.17.1