4.4. 使用 Jenkinsfile 创建管道
本节提供在使用 3scale toolbox 的 Groovy 中从头开始编写自定义 Jenkinsfile
的最佳实践。
红帽支持红帽集成存储库中提供的 Jenkins 管道示例。
对这些管道所做的任何修改都不受红帽直接支持。不支持您为环境创建的自定义管道。本节仅供参考。
先决条件
- 部署示例 Jenkins CI/CD 管道.
- 您的 API 必须具有 OpenAPI 规格文件。例如,您可以使用 Apicurio Studio 生成此操作。
步骤
编写一个工具函数来调用 3scale toolbox。下面创建一个运行 3scale toolbox 的 Kubernetes 作业:
#!groovy def runToolbox(args) { def kubernetesJob = [ "apiVersion": "batch/v1", "kind": "Job", "metadata": [ "name": "toolbox" ], "spec": [ "backoffLimit": 0, "activeDeadlineSeconds": 300, "template": [ "spec": [ "restartPolicy": "Never", "containers": [ [ "name": "job", "image": "registry.redhat.io/3scale-amp2/toolbox-rhel7:3scale2.9", "imagePullPolicy": "Always", "args": [ "3scale", "version" ], "env": [ [ "name": "HOME", "value": "/config" ] ], "volumeMounts": [ [ "mountPath": "/config", "name": "toolbox-config" ], [ "mountPath": "/artifacts", "name": "artifacts" ] ] ] ], "volumes": [ [ "name": "toolbox-config", "secret": [ "secretName": "3scale-toolbox" ] ], [ "name": "artifacts", "configMap": [ "name": "openapi" ] ] ] ] ] ] ] kubernetesJob.spec.template.spec.containers[0].args = args sh "rm -f -- job.yaml" writeYaml file: "job.yaml", data: kubernetesJob sh """set -e oc delete job toolbox --ignore-not-found sleep 2 oc create -f job.yaml sleep 20 # Adjust the sleep duration to your server velocity """ def logs = sh(script: "set -e; oc logs -f job/toolbox", returnStdout: true) echo logs return logs }
Kubernetes 对象模板
此功能使用 Kubernetes 对象模板来运行 3scale toolbox,您可以根据您的需要进行调整。它设置 3scale toolbox CLI 参数,并将生成的 Kubernetes 作业定义写入 YAML 文件,清理之前运行 toolbox,创建 Kubernetes 作业并等待:
-
您可以将等待持续时间调整到服务器速度,以匹配 Pod
在 Created
和Running 状态
之间过渡所需的时间。您可以使用轮询循环来优化此步骤。 -
OpenAPI 规格文件从名为
openapi 的
。ConfigMap
获取 -
3scale 管理门户主机名和访问令牌是从名为
3scale-toolbox
的 secret 获取的,如 安装 3scale toolbox 并启用访问权限 所示。 -
ConfigMap
将由管道在第 3 步中创建。但是,该 secret 已在管道外部置备,并受基于角色的访问控制(RBAC)的约束,以提高安全性。
-
您可以将等待持续时间调整到服务器速度,以匹配 Pod
在 Jenkins 管道阶段定义要用于 3scale toolbox 的全局环境变量。例如:
3scale Hosted
def targetSystemName = "saas-apikey-usecase" def targetInstance = "3scale-saas" def privateBaseURL = "http://echo-api.3scale.net" def testUserKey = "abcdef1234567890" def developerAccountId = "john"
3scale On-premises
使用自我管理的 APIcast 或 3scale 内部安装时,您必须再声明两个变量:
def publicStagingBaseURL = "http://my-staging-api.example.test" def publicProductionBaseURL = "http://my-production-api.example.test"
这些变量如下所述:
-
targetSystemName
:要创建的服务的名称。 -
targetInstance
:这与 安装 3scale toolbox 并启用访问权限时创建的 3scale 远程实例的名称匹配。 -
privateBaseURL
:API 后端的端点主机。 -
testUserKey
:用于运行集成测试的用户 API 密钥。可以像所示一样硬编码,或者从 HMAC 功能生成。 -
DeveloperAccountId
:在其中创建测试应用的目标帐户的 ID。 -
publicStagingBaseURL
:要创建的服务的公共暂存基础 URL。 -
publicProductionBaseURL
:要创建的服务的公共生产基础 URL。
-
添加 pipeline 阶段来获取 OpenAPI 规格文件,并将它作为
ConfigMap
在 OpenShift 中置备,如下所示:node() { stage("Fetch OpenAPI") { sh """set -e curl -sfk -o swagger.json https://raw.githubusercontent.com/microcks/api-lifecycle/master/beer-catalog-demo/api-contracts/beer-catalog-api-swagger.json oc delete configmap openapi --ignore-not-found oc create configmap openapi --from-file="swagger.json" """ }
添加一个使用 3scale toolbox 将 API 导入到 3scale 的管道阶段:
3scale Hosted
stage("Import OpenAPI") { runToolbox([ "3scale", "import", "openapi", "-d", targetInstance, "/artifacts/swagger.json", "--override-private-base-url=${privateBaseURL}", "-t", targetSystemName ]) }
3scale On-premises
使用自我管理的 APIcast 或 3scale 内部安装时,还必须指定公共暂存和生产基本 URL 的选项:
stage("Import OpenAPI") { runToolbox([ "3scale", "import", "openapi", "-d", targetInstance, "/artifacts/swagger.json", "--override-private-base-url=${privateBaseURL}", "-t", targetSystemName, "--production-public-base-url=${publicProductionBaseURL}", "--staging-public-base-url=${publicStagingBaseURL}" ]) }
添加使用 toolbox 创建 3scale 应用程序计划和应用程序的管道阶段:
stage("Create an Application Plan") { runToolbox([ "3scale", "application-plan", "apply", targetInstance, targetSystemName, "test", "-n", "Test Plan", "--default" ]) } stage("Create an Application") { runToolbox([ "3scale", "application", "apply", targetInstance, testUserKey, "--account=${developerAccountId}", "--name=Test Application", "--description=Created by Jenkins", "--plan=test", "--service=${targetSystemName}" ]) }
stage("Run integration tests") { def proxyDefinition = runToolbox([ "3scale", "proxy", "show", targetInstance, targetSystemName, "sandbox" ]) def proxy = readJSON text: proxyDefinition proxy = proxy.content.proxy sh """set -e echo "Public Staging Base URL is ${proxy.sandbox_endpoint}" echo "userkey is ${testUserKey}" curl -vfk ${proxy.sandbox_endpoint}/beer -H 'api-key: ${testUserKey}' curl -vfk ${proxy.sandbox_endpoint}/beer/Weissbier -H 'api-key: ${testUserKey}' curl -vfk ${proxy.sandbox_endpoint}/beer/findByStatus/available -H 'api-key: ${testUserKey}' """ }
添加使用 toolbox 将 API 提升到您的生产环境的阶段。
stage("Promote to production") { runToolbox([ "3scale", "proxy", "promote", targetInstance, targetSystemName ]) }