diff --git a/README.md b/README.md index 78f18e3..77920bc 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,21 @@ ## Setup +Create an OpenShift project to hold all your artefacts: + ```sh oc project api-lifecycle +``` + +Create a secret that contains all your [3scale remotes](https://github.com/3scale/3scale_toolbox/blob/master/docs/remotes.md): + +```sh 3scale remote add 3scale-saas https://$TOKEN@$TENANT.3scale.net/ 3scale remote add 3scale-onprem https://$TOKEN@$TENANT.$DOMAIN/ oc create secret generic 3scale-toolbox --from-file=$HOME/.3scalerc.yaml ``` -Deploy the API Backend: +Deploy the sample API Backend: ```sh oc project api-lifecycle @@ -17,11 +24,20 @@ oc new-app -i openshift/redhat-openjdk18-openshift:1.4 https://github.com/microc oc expose svc/beer-catalog --hostname=beer-catalog.app.itix.fr ``` +Deploy APIcast instances to be used in APIcast self-managed instances: + ```sh -oc process -f testcase-01/setup.yaml -p DEVELOPER_ACCOUNT_ID=2445582535751 -p PRIVATE_BASE_URL=http://beer-catalog.app.itix.fr |oc create -f - +oc create secret generic 3scale-tenant-saas --from-literal=password=https://$TOKEN@$TENANT-admin.3scale.net +oc create -f https://raw.githubusercontent.com/3scale/apicast/v3.4.0/openshift/apicast-template.yml +oc new-app --template=3scale-gateway --name=apicast-saas-staging -p CONFIGURATION_URL_SECRET=3scale-tenant-saas -p CONFIGURATION_CACHE=0 -p RESPONSE_CODES=true -p LOG_LEVEL=info -p CONFIGURATION_LOADER=lazy -p APICAST_NAME=apicast-saas-staging -p DEPLOYMENT_ENVIRONMENT=sandbox -p IMAGE_NAME=quay.io/3scale/apicast:v3.4.0 +oc new-app --template=3scale-gateway --name=apicast-saas-production -p CONFIGURATION_URL_SECRET=3scale-tenant-saas -p CONFIGURATION_CACHE=60 -p RESPONSE_CODES=true -p LOG_LEVEL=info -p CONFIGURATION_LOADER=boot -p APICAST_NAME=apicast-saas-production -p DEPLOYMENT_ENVIRONMENT=production -p IMAGE_NAME=quay.io/3scale/apicast:v3.4.0 +oc scale dc/apicast-saas-staging --replicas=1 +oc scale dc/apicast-saas-production --replicas=1 +oc create route edge apicast-saas-staging --service=apicast-saas-staging --hostname=wildcard.saas-staging.app.itix.fr --insecure-policy=Allow --wildcard-policy=Subdomain +oc create route edge apicast-saas-production --service=apicast-saas-production --hostname=wildcard.saas-production.app... --insecure-policy=Allow --wildcard-policy=Subdomain ``` -## Testcases +## Usecases | # | Format | Security | Target | Policies | |--------------------|--------|----------|----------------------------------|---------------------| @@ -32,3 +48,12 @@ oc process -f testcase-01/setup.yaml -p DEVELOPER_ACCOUNT_ID=2445582535751 -p PR | [05](testcase-05/) | YAML | API Key | Self-Managed, on-premises | URL rewriting | | [06](testcase-06/) | YAML | API Key | 3 envs on 1 tenant, Self-managed | - | | [07](testcase-07/) | JSON | OIDC | 3 envs on 3 tenants, on-premises | CORS, URL rewriting | + +### Usecase 01: Deploy a simple API on 3scale SaaS + +```sh +oc process -f testcase-01/setup.yaml -p DEVELOPER_ACCOUNT_ID=2445582535751 -p PRIVATE_BASE_URL=http://beer-catalog.app.itix.fr |oc create -f - +``` + +### Usecase 02: Deploy an API on 3scale SaaS with self-managed APIcast and 3scale on-premises + diff --git a/testcase-01/Jenkinsfile b/testcase-01/Jenkinsfile index 5f8ddea..d102dc2 100644 --- a/testcase-01/Jenkinsfile +++ b/testcase-01/Jenkinsfile @@ -1,12 +1,11 @@ #!groovy -library identifier: '3scale-toolbox-jenkins@add-features', +library identifier: '3scale-toolbox-jenkins@add-new-features', retriever: modernSCM([$class: 'GitSCMSource', - remote: 'https://github.com/nmasse-itix/3scale-toolbox-jenkins.git', + remote: 'https://github.com/rh-integration/3scale-toolbox-jenkins.git', traits: [[$class: 'jenkins.plugins.git.traits.BranchDiscoveryTrait']]]) def service = null -def testApplicationCredentials = null node() { stage('Checkout Source') { @@ -20,6 +19,9 @@ node() { privateBaseUrl: params.PRIVATE_BASE_URL ], toolbox: [openshiftProject: params.NAMESPACE, destination: params.TARGET_INSTANCE, secretName: params.SECRET_NAME], service: [:], + applications: [ + [ name: "my-test-app", description: "This is used for tests", plan: "test", account: params.DEVELOPER_ACCOUNT_ID ] + ], applicationPlans: [ [ systemName: "test", name: "Test", defaultPlan: true, published: true ], [ systemName: "silver", name: "Silver" ], @@ -40,15 +42,7 @@ node() { } stage("Create an Application") { - def testApplication = [ - name: "my-test-app", - description: "This is used for tests", - applicationPlan: "test", - accountId: params.DEVELOPER_ACCOUNT_ID - ] - - testApplicationCredentials = toolbox.getDefaultApplicationCredentials(service, testApplication.name) - service.applyApplication(testApplication + testApplicationCredentials) + service.applyApplication() } stage("Run integration tests") { @@ -56,9 +50,9 @@ node() { // to fetch the proxy definition to extract the staging public url def proxy = service.readProxy("sandbox") sh """set -e +x - curl -f -w "ListBeers: %{http_code}\n" -o /dev/null -s ${proxy.sandbox_endpoint}/api/beer -H 'api-key: ${testApplicationCredentials.userKey}' - curl -f -w "GetBeer: %{http_code}\n" -o /dev/null -s ${proxy.sandbox_endpoint}/api/beer/Weissbier -H 'api-key: ${testApplicationCredentials.userKey}' - curl -f -w "GetBeer: %{http_code}\n" -o /dev/null -s ${proxy.sandbox_endpoint}/api/beer/findByStatus/available -H 'api-key: ${testApplicationCredentials.userKey}' + curl -f -k -w "ListBeers: %{http_code}\n" -o /dev/null -s ${proxy.sandbox_endpoint}/api/beer -H 'api-key: ${service.applications[0].userkey}' + curl -f -k -w "GetBeer: %{http_code}\n" -o /dev/null -s ${proxy.sandbox_endpoint}/api/beer/Weissbier -H 'api-key: ${service.applications[0].userkey}' + curl -f -k -w "FindBeersByStatus: %{http_code}\n" -o /dev/null -s ${proxy.sandbox_endpoint}/api/beer/findByStatus/available -H 'api-key: ${service.applications[0].userkey}' """ } diff --git a/testcase-02/Jenkinsfile b/testcase-02/Jenkinsfile new file mode 100644 index 0000000..3efe785 --- /dev/null +++ b/testcase-02/Jenkinsfile @@ -0,0 +1,68 @@ +#!groovy + +library identifier: '3scale-toolbox-jenkins@add-new-features', + retriever: modernSCM([$class: 'GitSCMSource', + remote: 'https://github.com/rh-integration/3scale-toolbox-jenkins.git', + traits: [[$class: 'jenkins.plugins.git.traits.BranchDiscoveryTrait']]]) + +def service = null + +node() { + stage('Checkout Source') { + checkout scm + } + + stage("Prepare") { + service = toolbox.prepareThreescaleService( + openapi: [filename: "testcase-02/swagger.json"], + environment: [ baseSystemName: toolbox.generateRandomBaseSystemName(), + privateBaseUrl: params.PRIVATE_BASE_URL, + privateBasePath: "/api", + publicStagingWildcardDomain: params.PUBLIC_STAGING_WILDCARD_DOMAIN, + publicProductionWildcardDomain: params.PUBLIC_PRODUCTION_WILDCARD_DOMAIN ], + toolbox: [openshiftProject: params.NAMESPACE, destination: params.TARGET_INSTANCE, secretName: params.SECRET_NAME], + service: [:], + applications: [ + [ name: "my-test-app", description: "This is used for tests", plan: "test", account: params.DEVELOPER_ACCOUNT_ID ] + ], + applicationPlans: [ + [ systemName: "test", name: "Test", defaultPlan: true, published: true ], + [ systemName: "silver", name: "Silver" ], + [ systemName: "gold", name: "Gold" ], + ] + ) + + echo "toolbox version = " + service.toolbox.getToolboxVersion() + } + + stage("Import OpenAPI") { + service.importOpenAPI() + echo "Service with system_name ${service.environment.targetSystemName} created !" + } + + stage("Create an Application Plan") { + service.applyApplicationPlans() + } + + stage("Create an Application") { + service.applyApplication() + } + + stage("Run integration tests") { + // The staging and production base URLs are computed by the shared library + def proxy = [ + endpoint: service.environment.productionPublicBaseURL, + sandbox_endpoint: service.environment.stagingPublicBaseURL + ] + sh """set -e +x + curl -f -k -w "ListBeers: %{http_code}\n" -o /dev/null -s ${proxy.sandbox_endpoint}/api/beer + curl -f -k -w "GetBeer: %{http_code}\n" -o /dev/null -s ${proxy.sandbox_endpoint}/api/beer/Weissbier + curl -f -k -w "FindBeersByStatus: %{http_code}\n" -o /dev/null -s ${proxy.sandbox_endpoint}/api/beer/findByStatus/available + """ + } + + stage("Promote to production") { + service.promoteToProduction() + } + +} diff --git a/testcase-02/setup.yaml b/testcase-02/setup.yaml new file mode 100644 index 0000000..33f3aab --- /dev/null +++ b/testcase-02/setup.yaml @@ -0,0 +1,50 @@ +apiVersion: v1 +kind: Template +metadata: + name: testcase-02 +objects: +- kind: "BuildConfig" + apiVersion: "v1" + metadata: + name: "testcase-02" + namespace: ${NAMESPACE} + spec: + source: + git: + uri: ${GIT_REPO} + strategy: + type: "JenkinsPipeline" + jenkinsPipelineStrategy: + jenkinsfilePath: testcase-02/Jenkinsfile + env: + - name: SECRET_NAME + value: ${SECRET_NAME} + - name: NAMESPACE + value: ${NAMESPACE} + - name: TARGET_INSTANCE + value: ${TARGET_INSTANCE} + - name: PUBLIC_STAGING_WILDCARD_DOMAIN + value: ${PUBLIC_STAGING_WILDCARD_DOMAIN} + - name: PUBLIC_PRODUCTION_WILDCARD_DOMAIN + value: ${PUBLIC_PRODUCTION_WILDCARD_DOMAIN} + - name: DEVELOPER_ACCOUNT_ID + value: ${DEVELOPER_ACCOUNT_ID} + - name: PRIVATE_BASE_URL + value: ${PRIVATE_BASE_URL} +parameters: +- name: SECRET_NAME + value: 3scale-toolbox +- name: NAMESPACE + value: api-lifecycle +- name: TARGET_INSTANCE + required: true +- name: GIT_REPO + value: https://github.com/nmasse-itix/API-Lifecycle-Mockup.git +- name: PUBLIC_STAGING_WILDCARD_DOMAIN + required: true +- name: PUBLIC_PRODUCTION_WILDCARD_DOMAIN + required: true +- name: DEVELOPER_ACCOUNT_ID + required: true +- name: PRIVATE_BASE_URL + required: true