Featured capabilities:
- Allow interaction with the underlying 3scale API Management solution.
- Manage the 3scale application declaratively using openshift (custom) resources.
The following diagram shows 3scale entities and relations that will be eligible for management using openshift (custom) resources in a declarative way.
The following diagram shows available custom resource definitions and their relations provided by the 3scale operator.
- Application Capabilities
- Table of contents
- CRD Index
- Quickstart Guide
- Backend custom resource
- Product custom resource
- Product Deployment: Apicast Hosted
- Product Deployment: Apicast Self Managed
- Product authentication types
- Product metrics
- Product methods
- Product mapping rules
- Product application plans
- Product application plan limits
- Product application plan pricing rules
- Product backend usages
- Product policy chain
- Product custom gateway response on errors
- Product custom resource status field
- Link your 3scale product to your 3scale tenant or provider account
- ProxyConfigPromote custom resource
- OpenAPI custom resource
- ActiveDoc custom resource
- CustomPolicyDefinition Custom Resource
- Tenant custom resource
- DeveloperAccount custom resource
- DeveloperUser custom resource
- Application custom resource
- ApplicationAuth custom resource
- Limitations and unimplemented functionalities
- Application CRD reference
- CR samples [1]
- ApplicationAuth CRD reference
- CR samples [1]
- Backend CRD reference
- CR samples [1]
- Product CRD reference
- Tenant CRD reference
- CR samples [1]
- OpenAPI CRD reference
- DeveloperAccount CRD reference
- CR samples [1]
- DeveloperUser CRD reference
- ActiveDoc CRD reference
- CustomPolicyDefinition CRD reference
- CR samples [1]
- ProxyConfigPromote CRD reference
- CR samples [1]
To get up and running quickly, this quickstart guide will show how to deploy your first 3scale product and backend with the minimum required configuration.
Requirements
- Access to an OpenShift Container Platform 4.2 cluster.
- 3scale operator up and running. Installing through the OLM is quick and easy.
- Access to 3scale admin portal. Local in the working openshift namespace or remote 3scale. All you need is 3scale Admin URL and access token.
Steps
A) Create threescale-provider-account
secret with 3scale admin portal credentials. For example: adminURL=https://3scale-admin.example.com
and token=123456
.
oc create secret generic threescale-provider-account --from-literal=adminURL=https://3scale-admin.example.com --from-literal=token=123456
B) Setup 3scale backend with upstream api https://api.example.com
.
Create yaml file with the following content:
apiVersion: capabilities.3scale.net/v1beta1
kind: Backend
metadata:
name: backend1
spec:
name: "Operated Backend 1"
systemName: "backend1"
privateBaseURL: "https://api.example.com"
Check on the fields of Backend custom resource and possible values in the Backend CRD Reference documentation.
Create a custom resource:
oc create -f backend1.yaml
C) Setup 3scale product with all default settings using previously created backend
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
systemName: "operatedproduct1"
backendUsages:
backend1:
path: /
Check on the fields of Product custom resource and possible values in the Product CRD Reference documentation.
Create a custom resource:
oc create -f product1.yaml
Created custom resources will take a few seconds to setup your 3scale instance. You can check when resources are synchronized checking object's status
field conditions.
Or directly using oc wait
command:
oc wait --for=condition=Synced --timeout=-1s backend/backend1
oc wait --for=condition=Synced --timeout=-1s product/product1
It is assumed the reader is familiarized with 3scale backends.
The minimum configuration required to deploy and manage one 3scale backend is the Private Base URL and a name.
apiVersion: capabilities.3scale.net/v1beta1
kind: Backend
metadata:
name: backend-1
spec:
name: "My Backend Name"
privateBaseURL: "https://api.example.com"
Define desired backend metrics in your backend custom resource.
apiVersion: capabilities.3scale.net/v1beta1
kind: Backend
metadata:
name: backend-1
spec:
name: "My Backend Name"
privateBaseURL: "https://api.example.com"
metrics:
metric01:
friendlyName: Metric01
unit: "1"
metric02:
friendlyName: Metric02
unit: "1"
hits:
description: Number of API hits
friendlyName: Hits
unit: "hit"
Check on the fields of Backend custom resource and possible values in the Backend CRD Reference documentation.
- NOTE 1:
metrics
map key names will be used assystem_name
. In the example:metric01
,metric02
andhits
. - NOTE 2:
metrics
map key names must be unique among all metrics AND methods. - NOTE 3:
unit
andfriendlyName
fields are required. - NOTE 4:
hits
metric will be created by the operator for you if not present.
Define desired backend methods in your backend custom resource.
apiVersion: capabilities.3scale.net/v1beta1
kind: Backend
metadata:
name: backend-1
spec:
name: "My Backend Name"
privateBaseURL: "https://api.example.com"
methods:
method01:
friendlyName: Method01
method02:
friendlyName: Method02
Check on the fields of Backend custom resource and possible values in the Backend CRD Reference documentation.
- NOTE 1:
methods
map key names will be used assystem_name
. In the example:method01
andmethod02
. - NOTE 2:
methods
map key names must be unique among all metrics AND methods. - NOTE 3:
friendlyName
field is required.
apiVersion: capabilities.3scale.net/v1beta1
kind: Backend
metadata:
name: backend-1
spec:
name: "My Backend Name"
privateBaseURL: "https://api.example.com"
mappingRules:
- httpMethod: GET
pattern: "/pets"
increment: 1
metricMethodRef: hits
- httpMethod: GET
pattern: "/pets/id"
increment: 1
metricMethodRef: hits
metrics:
hits:
description: Number of API hits
friendlyName: Hits
unit: "hit"
Check on the fields of Backend custom resource and possible values in the Backend CRD Reference documentation.
- NOTE 1:
httpMethod
,pattern
,increment
andmetricMethodRef
fields are required. - NOTE 2:
metricMethodRef
holds a reference to the existing metric or method map key namesystem_name
. In the example,hits
.
The status field shows resource information useful for the end user. It is not regarded to be updated manually and it is being reconciled on every change of the resource.
Fields:
- backendId: 3scale bakend internal ID
- conditions: status.Conditions k8s common pattern. States:
- Failed: Indicates that an error occurred during synchronization. The operator will retry.
- Synced: Indicates the backend has been successfully synchronized.
- Invalid: Invalid object. This is not a transient error, but it reports about invalid spec and should be changed. The operator will not retry.
- observedGeneration: helper field to see if status info is up to date with latest resource spec.
- providerAccountHost: 3scale provider account URL to which the backend is synchronized.
Example of Synced resource.
status:
backendId: 59978
conditions:
- lastTransitionTime: "2020-06-22T10:50:33Z"
status: "False"
type: Failed
- lastTransitionTime: "2020-06-22T10:50:33Z"
status: "False"
type: Invalid
- lastTransitionTime: "2020-06-22T10:50:33Z"
status: "True"
type: Synced
observedGeneration: 2
providerAccountHost: https://3scale-admin.example.com
When some 3scale resource is found by the 3scale operator, LookupProviderAccount process is started to figure out the tenant owning the resource.
The process will check the following tenant credential sources. If none is found, an error is raised.
- Read credentials from providerAccountRef resource attribute. This is a secret local reference, for instance
mytenant
apiVersion: capabilities.3scale.net/v1beta1
kind: Backend
metadata:
name: backend-1
spec:
name: "My Backend Name"
privateBaseURL: "https://api.example.com"
providerAccountRef:
name: mytenant
The mytenant
secret must haveadminURL
and token
fields with tenant credentials. For example:
apiVersion: v1
kind: Secret
metadata:
name: mytenant
type: Opaque
stringData:
adminURL: https://my3scale-admin.example.com:443
token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- Default
threescale-provider-account
secret
For example: adminURL=https://3scale-admin.example.com
and token=123456
.
oc create secret generic threescale-provider-account --from-literal=adminURL=https://3scale-admin.example.com --from-literal=token=123456
- Default provider account in the same namespace 3scale deployment
The operator will gather required credentials automatically for the default 3scale tenant (provider account) if 3scale installation is found in the same namespace as the custom resource.
It is assumed the reader is familiarized with 3scale products.
The minimum configuration required to deploy and manage one 3scale product is the name.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
Configure your product with Apicast Hosted deployment mode
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
deployment:
apicastHosted: {}
Configure your product with Apicast Self Managed deployment mode
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
deployment:
apicastSelfManaged:
stagingPublicBaseURL: "https://staging.api.example.com"
productionPublicBaseURL: "https://production.api.example.com"
The application is identified & authenticated via a single string.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
deployment:
<any>:
authentication:
userkey:
authUserKey: myKey
Check Product CRD Reference documentation for all the details.
The application is identified via the App_ID and authenticated via the App_Key.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
deployment:
<any>:
authentication:
appKeyAppID:
appID: myAppID
appKey: myAppKey
- NOTE 1:
appID
is the name of the parameter that acts of behalf of app id. - NOTE 2:
appKey
is the name of the parameter that acts of behalf of app key.
Check Product CRD Reference documentation for all the details.
Use OpenID Connect for any OAuth 2.0 flow.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
deployment:
<any>:
authentication:
oidc:
issuerType: "keycloak"
issuerEndpoint: "https://myclientid:[email protected]/auth/realms/myrealm"
authenticationFlow:
standardFlowEnabled: false
implicitFlowEnabled: true
serviceAccountsEnabled: true
directAccessGrantsEnabled: true
jwtClaimWithClientID: "azp"
jwtClaimWithClientIDType: "plain"
- NOTE 1:
issuerType
andissuerEndpoint
fields are required. - NOTE 2:
issuerType
Defines the type of the issuer with the following valid types:keycloak
: Red Hat Single Sign-Onrest
: Rest API
- NOTE 3:
issuerEndpoint
defines the location of your OpenID Provider. The format of this endpoint is determined on your OpenID Provider setup. A common guidance would behttps://<CLIENT_ID>:<CLIENT_SECRET>@<HOST>:<PORT>/auth/realms/<REALM_NAME>
- NOTE 4: The credentials (CLIENT_ID and CLIENT_CREDENTIALS) provided in
issuerEndpoint
should have sufficient permissions to manage other clients in the realm.
Check Product CRD Reference documentation for all the details.
Define desired product metrics using the metrics object.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
metrics:
metric01:
friendlyName: Metric01
unit: "1"
hits:
description: Number of API hits
friendlyName: Hits
unit: "hit"
- NOTE 1:
metrics
map key names will be used assystem_name
. In the example:metric01
andhits
. - NOTE 2:
hits
metric will be created by the operator for you if not present. - NOTE 3:
metrics
map key names must be unique among all metrics AND methods. - NOTE 4:
unit
andfriendlyName
fields are required.
Define desired product methods using the methods object.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
methods:
method01:
friendlyName: Method01
method02:
friendlyName: Method02
- NOTE 1:
methods
map key names will be used assystem_name
. In the example:method01
andmethod02
. - NOTE 2:
methods
map key names must be unique among all metrics AND methods. - NOTE 3:
friendlyName
field is required.
Define desired product mapping rules declaratively using the mappingRules
object.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
metrics:
hits:
description: Number of API hits
friendlyName: Hits
unit: "hit"
methods:
method01:
friendlyName: Method01
mappingRules:
- httpMethod: GET
pattern: "/pets"
increment: 1
metricMethodRef: hits
- httpMethod: GET
pattern: "/cars"
increment: 1
metricMethodRef: method01
- NOTE 1:
httpMethod
,pattern
,increment
andmetricMethodRef
fields are required. - NOTE 2:
metricMethodRef
holds a reference to the existing metric or method map key namesystem_name
. In the example,hits
. - NOTE 3: If you update Product CR and delete both Method and Mapping Rule using this method - please expect following behavior:
- the Mapping Rule will be deleted immediately in 3scale Portal - Product/Integration/Mapping Rules
- If the configuration was promoted to stage or/and production a warning appears in Product CR informing that the Method is used by the latest gateway configuration, it will be removed from 3scale only once the promotion without the mapping rule that uses the deleted method is done.
Define desired product application plans declaratively using the applicationPlans
object.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
applicationPlans:
plan01:
name: "My Plan 01"
setupFee: "14.56"
plan02:
name: "My Plan 02"
trialPeriod: 3
costMonth: 3
- NOTE 1:
applicationPlans
map key names will be used assystem_name
. In the example:plan01
andplan02
.
Define the desired product application plan limits declaratively using the applicationPlans.limits
list.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
metrics:
hits:
description: Number of API hits
friendlyName: Hits
unit: "hit"
applicationPlans:
plan01:
name: "My Plan 01"
limits:
- period: month
value: 300
metricMethodRef:
systemName: hits
backend: backendA
- period: week
value: 100
metricMethodRef:
systemName: hits
- NOTE 1:
period
,value
andmetricMethodRef
fields are required. - NOTE 2:
metricMethodRef
reference can be product or backend reference. Usebackend
optional field to reference metric's backend owner.
Define desired product application plan pricing rules declaratively using the applicationPlans.pricingRules
list.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
metrics:
hits:
description: Number of API hits
friendlyName: Hits
unit: "hit"
applicationPlans:
plan01:
name: "My Plan 01"
pricingRules:
- from: 1
to: 100
pricePerUnit: "15.45"
metricMethodRef:
systemName: hits
- from: 1
to: 300
pricePerUnit: "15.45"
metricMethodRef:
systemName: hits
backend: backendA
- NOTE 1:
from
,to
,pricePerUnit
andmetricMethodRef
fields are required. - NOTE 2:
metricMethodRef
reference can be product or backend reference. Usebackend
optional field to reference metric's backend owner. - NOTE 3:
from
andto
will be validated.from
<to
for any rule and overlapping ranges for the same metric is not allowed.
Define desired product backend usages declaratively using the backendUsages
object.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
backendUsages:
backendA:
path: /A
backendB:
path: /B
- NOTE 1:
backendUsages
map key names are references toBackend system_name
. In the example:backendA
andbackendB
. - NOTE 2:
path
field is required.
Define desired product policy chain declaratively using the policies
object.
The policy configuration can be defined in plain text using the configuration
field, for example:
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
policies:
- configuration:
http_proxy: http://example.com
https_proxy: https://example.com
enabled: true
name: camel
version: builtin
- configuration: {}
enabled: true
name: apicast
version: builtin
- NOTE 1:
apicast
policy item will be added by the operator if not included.
Alternatively, the configuration for a given policy can be referenced in a secret. This is particularly interesting when the configuration contains sensitive data.
For example, let's create a secret called my-caching-config
with the configuration for the Content caching
policy:
oc apply -f - <<END
---
apiVersion: v1
kind: Secret
metadata:
name: my-caching-config
type: Opaque
stringData:
configuration: |
{
"rules": [
{
"header": "X-Cache-Status",
"condition": {
"operations": [
{
"left_type": "plain",
"right_type": "plain",
"op": "==",
"right": "GET",
"left": "ein"
},
{
"left_type": "plain",
"right_type": "plain",
"op": "!=",
"right": "RIGHTein",
"left": "elftein"
}
],
"combine_op": "and"
},
"cache": true
}
]
}
END
NOTE 1:
configuration
field must be used to contain the policy configuration.
NOTE 2: The configuration value must be
json
encoded value.
This secret can then be referenced using the configurationRef
field in the policy.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
policies:
- configurationRef:
name: my-caching-config
name: content_caching
version: builtin
enabled: true
Policy chain of a 3scale product can be exported using the 3scale Toolbox export command
$ 3scale policies export <MY-3SCALE-PROVIDER-ACCOUNT> <MY-PRODUCT>
---
- name: apicast
version: builtin
configuration: {}
enabled: true
- name: content_caching
version: builtin
configuration:
rules:
- header: X-Cache-Status
condition:
operations:
- left_type: plain
right_type: plain
op: "=="
right: GET
left: ein
- left_type: plain
right_type: plain
op: "!="
right: RIGHTein
left: elftein
combine_op: and
cache: true
enabled: true
- name: camel
version: builtin
configuration:
https_proxy: https://example.com
http_proxy: http://example.com
enabled: true
Define desired product custom gateway reponse on errors declaratively using the gatewayResponse
object.
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
deployment:
apicastHosted:
authentication:
userkey:
gatewayResponse:
errorStatusAuthFailed: 500
errorHeadersAuthFailed: "text/plain; charset=mycharset"
errorAuthFailed: "My custom reponse body"
errorStatusAuthMissing: 500
errorHeadersAuthMissing: "text/plain; charset=mycharset"
errorAuthMissing: "My custom reponse body"
errorStatusNoMatch: 501
errorHeadersNoMatch: "text/plain; charset=mycharset"
errorNoMatch: "My custom reponse body"
errorStatusLimitsExceeded: 502
errorHeadersLimitsExceeded: "text/plain; charset=mycharset"
errorLimitsExceeded: "My custom reponse body"
- NOTE 1: The
gatewayResponse
optional field my be set in several different deployment options. The example just shows it for the apicast hosted deployment option and the authentication mode called UserKey.
Check Product CRD Reference documentation for all the details.
The status field shows resource information useful for the end user. It is not regarded to be updated manually and it is being reconciled on every change of the resource.
Fields:
- productId: 3scale product internal ID
- conditions: status.Conditions k8s common pattern. States:
- Failed: Indicates that an error occurred during synchronization. The operator will retry.
- Synced: Indicates the product has been successfully synchronized.
- Invalid: Invalid object. This is not a transient error, but it reports about invalid spec and should be changed. The operator will not retry.
- Orphan: Spec references non existing resource. The operator will retry.
- observedGeneration: helper field to see if status info is up to date with latest resource spec.
- state: 3scale product internal state read from 3scale API.
- providerAccountHost: 3scale provider account URL to which the backend is synchronized.
Example of Synced resource.
status:
conditions:
- lastTransitionTime: "2020-10-21T18:07:01Z"
status: "False"
type: Failed
- lastTransitionTime: "2020-10-21T18:06:54Z"
status: "False"
type: Invalid
- lastTransitionTime: "2020-10-21T18:07:01Z"
status: "False"
type: Orphan
- lastTransitionTime: "2020-10-21T18:07:01Z"
status: "True"
type: Synced
observedGeneration: 1
productId: 2555417872138
providerAccountHost: https://3scale-admin.example.com
state: incomplete
When some 3scale resource is found by the 3scale operator, LookupProviderAccount process is started to figure out the tenant owning the resource.
The process will check the following tenant credential sources. If none is found, an error is raised.
- Read credentials from providerAccountRef resource attribute. This is a secret local reference, for instance
mytenant
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1
spec:
name: "OperatedProduct 1"
providerAccountRef:
name: mytenant
The mytenant
secret must haveadminURL
and token
fields with tenant credentials. For example:
apiVersion: v1
kind: Secret
metadata:
name: mytenant
type: Opaque
stringData:
adminURL: https://my3scale-admin.example.com:443
token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- Default
threescale-provider-account
secret
For example: adminURL=https://3scale-admin.example.com
and token=123456
.
oc create secret generic threescale-provider-account --from-literal=adminURL=https://3scale-admin.example.com --from-literal=token=123456
- Default provider account in the same namespace 3scale deployment
The operator will gather required credentials automatically for the default 3scale tenant (provider account) if 3scale installation is found in the same namespace as the custom resource.
- Used for promoting Products to staging and production ProxyConfigPromote are a one off action i.e. a button click event.
Say you have a product e.g. product1-cr
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1-cr
spec:
name: product1
backendUsages:
backend1:
path: /
Create proxyconfigpromote resources to promote product to staging.
apiVersion: capabilities.3scale.net/v1beta1
kind: ProxyConfigPromote
metadata:
name: product1-v1-staging
spec:
productCRName: product1-cr
This will promote the product created by product1-cr to staging We can also promote directly to production with the production bool set to true
apiVersion: capabilities.3scale.net/v1beta1
kind: ProxyConfigPromote
metadata:
name: product1-v1-production
namespace: 3scale-test
spec:
productCRName: product1-cr
production: true
deleteCR: true
Note the deleteCR bool is set to true this will delete the ProxyConfigPromote CR once successfully promoted.
ProxyConfigPromote CRD reference
Fields:
- conditions: status.Conditions k8s common pattern. States:
- Ready: Indicates the keys have successfully updated.
- Failed: Indicates the keys have not successfully updated.
- latestProductionVersion: returns the latest production version after product promotion
- latestStagingVersion: returns the latest staging version after product promotion
- productId: returns the product ID that was promoted
e.g. of a Successful status
status:
conditions:
- lastTransitionTime: '2022-05-11T13:41:00Z'
message: >-
3scale product has been successfully promoted, any further interactions
with this CR (apart from deletion) won't be applied
status: 'True'
type: Ready
latestProductionVersion: 7
latestStagingVersion: 8
productId: '3'
e.g. of a product with nothing to promote
status:
conditions:
- lastTransitionTime: '2023-09-05T07:48:08Z'
message: >-
can't promote to production as no product changes detected, delete the
proxyConfigPromote CR or introduce changes to stage env first to proceed
status: 'True'
type: Failed
latestProductionVersion: 1
latestStagingVersion: 1
productId: '6'
- OpenAPI 3.X specification
- Accepted OpenAPI spec document formats are
json
andyaml
. - OpenAPI spec document can be read from:
- Secret
- URL. Supported schemes are
http
andhttps
- Optionally, link the activedoc with a 3scale product using the
productSystemName
field. The value must be thesystem_name
of the 3scale product's CR. The referenced 3scale product must exist as CR, it cannot be some unmanaged 3scale product's system name. - Publish or hide the activedoc using the
published
field. By default, it will behidden
. - Skip OpenAPI 3.0 validations using the
skipSwaggerValidations
field. By default, the activedoc will be validated.
Create a secret with the OpenAPI spec document. The name of the secret object will be referenced in the ActiveDoc CR.
The following example shows how to create a secret out of a file:
$ cat myopenapi.yaml
---
openapi: "3.0.0"
info:
title: "some title"
version: "1.0.0"
$ oc create secret generic myopenapi --from-file myopenapi.yaml
secret/myopenapi created
NOTE The field name inside the secret is not read by the operator. Only the content is read.
NOTE The secret is not monitored for updates. If the secret is updated after being created, the ActiveDoc custom resource has to be updated to force reconcilliation. It is safe to delete the status
field to force the reconcilliation and the operator will re-create the status
field again.
Then, create your ActiveDoc CR providing reference to the secret holding the OpenAPI document.
apiVersion: capabilities.3scale.net/v1beta1
kind: ActiveDoc
metadata:
name: activedoc-secret
spec:
name: "Operated ActiveDoc From secret"
activeDocOpenAPIRef:
secretRef:
name: myopenapi
ActiveDoc CRD Reference for more info about fields.
apiVersion: capabilities.3scale.net/v1beta1
kind: ActiveDoc
metadata:
name: activedoc-from-url
spec:
name: "Operated ActiveDoc From URL"
activeDocOpenAPIRef:
url: "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.json"
ActiveDoc CRD Reference for more info about fields.
One Product custom resource can be linked to the ActiveDoc custom resource. The ActiveDoc custom resource cannot be linked to an unmanaged 3scale product by the system name.
apiVersion: capabilities.3scale.net/v1beta1
kind: ActiveDoc
metadata:
name: activedoc-with-product-link
spec:
name: "Operated ActiveDoc"
openapiRef:
url: "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml"
productSystemName: myPetProduct
ActiveDoc CRD Reference for more info about fields.
When some ActiveDoc custom resource is found by the 3scale operator, LookupProviderAccount process is started to figure out the tenant owning the resource.
The process will check the following tenant credential sources. If none is found, an error is raised.
- Read credentials from providerAccountRef resource attribute. This is a secret local reference, for instance
mytenant
apiVersion: capabilities.3scale.net/v1beta1
kind: ActiveDoc
metadata:
name: activedoc1
spec:
name: "Operated ActiveDoc"
openapiRef:
url: "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml"
providerAccountRef:
name: mytenant
ActiveDoc CRD Reference for more info about fields.
The mytenant
secret must haveadminURL
and token
fields with tenant credentials. For example:
apiVersion: v1
kind: Secret
metadata:
name: mytenant
type: Opaque
stringData:
adminURL: https://my3scale-admin.example.com:443
token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- Default
threescale-provider-account
secret
For example: adminURL=https://3scale-admin.example.com
and token=123456
.
oc create secret generic threescale-provider-account --from-literal=adminURL=https://3scale-admin.example.com --from-literal=token=123456
- Default provider account in the same namespace 3scale deployment
The operator will gather required credentials automatically for the default 3scale tenant (provider account) if 3scale installation is found in the same namespace as the custom resource.
Example:
apiVersion: capabilities.3scale.net/v1beta1
kind: CustomPolicyDefinition
metadata:
name: custompolicydefinition-sample
spec:
name: "MyCustomPolicy"
version: "0.0.1"
schema:
name: "MyCustomPolicy"
version: "0.0.1"
summary: "some summary"
$schema: "http://json-schema.org/draft-07/schema#"
configuration:
type: "object"
properties:
someAttr:
description: "Some attribute"
type: "integer"
CustomPolicyDefinition CRD Reference for more info about fields.
When some CustomPolicyDefinition custom resource is found by the 3scale operator, LookupProviderAccount process is started to figure out the tenant owning the resource.
The process will check the following tenant credential sources. If none is found, an error is raised.
- Read credentials from providerAccountRef resource attribute. This is a secret local reference, for instance
mytenant
apiVersion: capabilities.3scale.net/v1beta1
kind: CustomPolicyDefinition
metadata:
name: custompolicydefinition-sample
spec:
name: "MyCustomPolicy"
version: "0.0.1"
schema:
name: "MyCustomPolicy"
version: "0.0.1"
summary: "some summary"
$schema: "http://json-schema.org/draft-07/schema#"
configuration:
type: "object"
properties:
someAttr:
description: "Some attribute"
type: "integer"
providerAccountRef:
name: mytenant
CustomPolicyDefinition CRD Reference for more info about fields.
The mytenant
secret must haveadminURL
and token
fields with tenant credentials. For example:
apiVersion: v1
kind: Secret
metadata:
name: mytenant
type: Opaque
stringData:
adminURL: https://my3scale-admin.example.com:443
token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- Default
threescale-provider-account
secret
For example: adminURL=https://3scale-admin.example.com
and token=123456
.
oc create secret generic threescale-provider-account --from-literal=adminURL=https://3scale-admin.example.com --from-literal=token=123456
- Default provider account in the same namespace 3scale deployment
The operator will gather required credentials automatically for the default 3scale tenant (provider account) if 3scale installation is found in the same namespace as the custom resource.
Tenant is also known as Provider Account.
Creating the APIManager custom resource tells the operator to deploy 3scale. Default 3scale installation includes a default tenant ready to be used. Optionally, you may create other tenants creating Tenant custom resource objects.
To deploy a new tenant in your 3scale instance, first, you need some preparation steps:
- Create or local 3scale Master credentials secret: MASTER_SECRET
- Create a new secret to store the password for the admin account of the new tenant: ADMIN_SECRET
- Get the 3scale master account hostname: MASTER_HOSTNAME
A) 3scale Master credentials secret: MASTER_SECRET
Tenant management can only be done using 3scale master account. You need master account credentials (preferably an access token).
-
If the tenant resource is created in the same namespace as 3scale, the secret with master account credentials has been created already and it is called system-seed.
-
If the tenant resource is not created in the same namespace as 3scale, you need to create a secret with the master account credentials.
oc create secret generic system-seed --from-literal=MASTER_ACCESS_TOKEN=<master access token>
Note: the name of the secret is optional. The secret name will be used in the tenant custom resource.
B) Create a new secret to store the password for the admin account of the new tenant: ADMIN_SECRET
oc create secret generic ecorp-admin-secret --from-literal=admin_password=<admin password value>
Note: the name of the secret is optional. The secret name will be used in the tenant custom resource.
C) Get 3scale master account hostname: MASTER_HOSTNAME
When you deploy 3scale using the operator, the master account has a fixed URL: master.${wildcardDomain}
- If you have access to the namespace where 3scale is installed, the master account hostname can be easily obtained:
oc get routes --field-selector=spec.to.name==system-master -o jsonpath="{.items[].spec.host}"
apiVersion: capabilities.3scale.net/v1alpha1
kind: Tenant
metadata:
name: ecorp-tenant
spec:
username: admin
systemMasterUrl: https://<MASTER_HOSTNAME>
email: [email protected]
organizationName: ECorp
masterCredentialsRef:
name: <MASTER_SECRET>
passwordCredentialsRef:
name: <ADMIN_SECRET*>
tenantSecretRef:
name: tenant-secret
You can set the following optional parameters in Tenant
CR:
- fromEmail
- supportEmail
- financeSupportEmail
- siteAccessCode
apiVersion: capabilities.3scale.net/v1alpha1
kind: Tenant
metadata:
name: ecorp-tenant
spec:
username: admin
systemMasterUrl: https://<MASTER_HOSTNAME>
email: [email protected]
organizationName: ECorp
masterCredentialsRef:
name: <MASTER_SECRET>
passwordCredentialsRef:
name: <ADMIN_SECRET*>
tenantSecretRef:
name: tenant-secret
fromEmail: <tenantFromEmail>
supportEmail: <tenantSupportEmail>
financeSupportEmail: <tenantFinanceSupportEmail>
siteAccessCode: <abc123>
Check on the fields of Tenant Custom Resource and possible values in the Tenant CRD Reference documentation.
Create the tenant resource:
oc create -f <yaml-name>
This should trigger the creation of a new tenant in your 3scale API Management solution.
The 3scale operator will create a new secret and store the new tenant's credentials in it. The new tenant provider_key and admin domain url will be stored in a secret. The secret location can be specified using tenantSecretRef tenant spec key.
Example of the created secret content:
apiVersion: v1
kind: Secret
metadata:
name: tenant-secret
type: Opaque
stringData:
adminURL: https://my3scale-admin.example.com:443
token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Refer to Tenant CRD Reference documentation for more information.
If a tenant has been created via CR it can be marked for deletion in 3scale API Management solution by deleting the tenant CR.
The minimum configuration required to deploy and manage one 3scale developer account is:
- Provide, at least, the organization name in the
spec.OrgName
field. - Create one DeveloperUser CR with the
admin
role. Without any admin developer user custom resource deployed, the account cannot be created. Like any other tenant owned entities, the developer account needs to be linked to some 3scale tenant or provider account.
Custom resource example:
apiVersion: capabilities.3scale.net/v1beta1
kind: DeveloperAccount
metadata:
name: developeraccount-simple-sample
spec:
orgName: Ecorp
The status field shows resource information useful for the end user. It is not regarded to be updated manually and it is being reconciled on every change of the resource.
Fields:
- accountID: developer account internal ID
- accountState: developer account state
- creditCardStored: info about credit card
- conditions: status.Conditions k8s common pattern. States:
- Invalid: Invalid object. This is not a transient error, but it reports about invalid spec and should be changed. The operator will not retry.
- Failed: Indicates that an error occurred during synchronization. The operator will retry.
- Ready: Indicates the account has been successfully synchronized.
- Waiting: Indicates the account is waiting for some event to happen. The operator will retry.
- observedGeneration: helper field to see if status info is up to date with latest resource spec.
- providerAccountHost: 3scale provider account URL to which the backend is synchronized.
Example of Ready resource.
status:
accountID: 2445583436906
accountState: approved
conditions:
- lastTransitionTime: "2021-02-17T23:39:00Z"
status: "False"
type: Failed
- lastTransitionTime: "2021-02-17T23:39:00Z"
status: "False"
type: Invalid
- lastTransitionTime: "2021-02-17T23:39:00Z"
status: "True"
type: Ready
- lastTransitionTime: "2021-02-17T23:39:00Z"
status: "False"
type: Waiting
creditCardStored: false
observedGeneration: 1
providerAccountHost: https://3scale-admin.example.com
When some openapi custom resource is found by the 3scale operator, LookupProviderAccount process is started to figure out the tenant owning the resource.
The process will check the following tenant credential sources. If none is found, an error is raised.
- Read credentials from providerAccountRef resource attribute. This is a secret local reference, for instance
mytenant
apiVersion: capabilities.3scale.net/v1beta1
kind: DeveloperAccount
metadata:
name: developeraccount-simple-sample
spec:
orgName: Ecorp
providerAccountRef:
name: mytenant
DeveloperAccont CRD reference for more info about fields.
The mytenant
secret must haveadminURL
and token
fields with tenant credentials. For example:
apiVersion: v1
kind: Secret
metadata:
name: mytenant
type: Opaque
stringData:
adminURL: https://my3scale-admin.example.com:443
token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- Default
threescale-provider-account
secret
For example: adminURL=https://3scale-admin.example.com
and token=123456
.
oc create secret generic threescale-provider-account --from-literal=adminURL=https://3scale-admin.example.com --from-literal=token=123456
- Default provider account in the same namespace 3scale deployment
The operator will gather required credentials automatically for the default 3scale tenant (provider account) if 3scale installation is found in the same namespace as the custom resource.
Notes:
- 3scale developer users belong to some developer account. Therefore, the
DeveloperUser
custom resource requires a reference to one DeveloperAccount CR email
andusername
fields are unique among all developer users of the tenant.- The password for the developer user will be provided in a referenced secret in the
passwordCredentialsRef
field. - Developer users have the role of
admin
ormember
.
Before creating the developer user custom resource, create a new secret to store the password
$ cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: developeruserpassword
stringData:
password: <password value>
$ oc apply -f secret.yaml
Alternatively
oc create secret generic developeruserpassword --from-literal=password=<password value>
apiVersion: capabilities.3scale.net/v1beta1
kind: DeveloperUser
metadata:
name: developeruser-member-sample
spec:
username: myusername1
email: [email protected]
role: member
passwordCredentialsRef:
name: developeruserpassword
developerAccountRef:
name: developeraccount-simple-sample
apiVersion: capabilities.3scale.net/v1beta1
kind: DeveloperUser
metadata:
name: developeruser-member-sample
spec:
username: myusername1
email: [email protected]
role: admin
passwordCredentialsRef:
name: developeruserpassword
developerAccountRef:
name: developeraccount-simple-sample
The status field shows resource information useful for the end user. It is not regarded to be updated manually and it is being reconciled on every change of the resource.
Fields:
- developerUserID: developer user internal ID
- developerUserState: developer user state
- accountID: developer account internal ID to which developer user is linked
- conditions: status.Conditions k8s common pattern. States:
- Invalid: Invalid object. This is not a transient error, but it reports about invalid spec and should be changed. The operator will not retry.
- Failed: Indicates that an error occurred during synchronization. The operator will retry.
- Ready: Indicates the account has been successfully synchronized.
- Orphan: Spec references non existing resource. The operator will retry.
- observedGeneration: helper field to see if status info is up to date with latest resource spec.
- providerAccountHost: 3scale provider account URL to which the backend is synchronized.
Example of Ready resource.
status:
accoundID: 2445583436906
conditions:
- lastTransitionTime: "2021-02-17T23:38:48Z"
status: "False"
type: Failed
- lastTransitionTime: "2021-02-17T23:38:48Z"
status: "False"
type: Invalid
- lastTransitionTime: "2021-02-17T23:39:09Z"
status: "False"
type: Orphan
- lastTransitionTime: "2021-02-17T23:39:09Z"
status: "True"
type: Ready
developerUserID: 2445583628982
developerUserState: active
observedGeneration: 1
providerAccountHost: https://3scale-admin.example.com
When some openapi custom resource is found by the 3scale operator, LookupProviderAccount process is started to figure out the tenant owning the resource.
The process will check the following tenant credential sources. If none is found, an error is raised.
- Read credentials from providerAccountRef resource attribute. This is a secret local reference, for instance
mytenant
apiVersion: capabilities.3scale.net/v1beta1
kind: DeveloperUser
metadata:
name: developeruser-member-sample
spec:
username: myusername1
email: [email protected]
passwordCredentialsRef:
name: developeruserpassword
developerAccountRef:
name: developeraccount-simple-sample
providerAccountRef:
name: mytenant
DeveloperUser CRD reference for more info about fields.
The mytenant
secret must haveadminURL
and token
fields with tenant credentials. For example:
apiVersion: v1
kind: Secret
metadata:
name: mytenant
type: Opaque
stringData:
adminURL: https://my3scale-admin.example.com:443
token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- Default
threescale-provider-account
secret
For example: adminURL=https://3scale-admin.example.com
and token=123456
.
oc create secret generic threescale-provider-account --from-literal=adminURL=https://3scale-admin.example.com --from-literal=token=123456
- Default provider account in the same namespace 3scale deployment
The operator will gather required credentials automatically for the default 3scale tenant (provider account) if 3scale installation is found in the same namespace as the custom resource.
Notes:
- 3scale applications belong to some DeveloperAccount account.
- 3scale applications are linked directly to a product and applicationPlan
Consider we have the following product which is connected to a backend
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
name: product1-cr
spec:
applicationPlans:
plan01:
name: "My Plan 01"
limits:
- period: month
value: 300
metricMethodRef:
systemName: hits
backend: backend1
plan02:
name: "My Plan 02"
limits:
- period: month
value: 300
metricMethodRef:
systemName: hits
backend: backend1
name: product1
backendUsages:
backend1:
path: /
And the following developerAccount
apiVersion: capabilities.3scale.net/v1beta1
kind: DeveloperAccount
metadata:
name: developeraccount01
spec:
orgName: Ecorp
providerAccountRef:
name: mytenant
You will need the product CR name, developerAccount CR name and the application plan name from the product CR to create an application as follows, giving it a name and description
apiVersion: capabilities.3scale.net/v1beta1
kind: Application
metadata:
name: example
spec:
accountCR:
name: developeraccount01
applicationPlanName: plan01
productCR:
name: product1-cr
name: application-name
description: description of application
You can suspend an existing application by updating the spec.suspend
bool in the application CR
apiVersion: capabilities.3scale.net/v1beta1
kind: Application
metadata:
name: example
spec:
accountCR:
name: developeraccount01
applicationPlanName: plan02
productCR:
name: product1-cr
name: testApp12
description: further testing12
suspend: true
You will see the status.state
update from live to suspended
status:
applicationID: 1
conditions:
- lastTransitionTime: '2022-11-01T14:22:14Z'
status: 'True'
type: Ready
observedGeneration: 2
providerAccountHost: 'https://3scale-admin.example.com'
state: suspended
Application CRD reference for more info about fields.
Fields:
- applicationID: application internal ID
- conditions: status.Conditions k8s common pattern. States:
- Ready: Indicates the account has been successfully synchronized.
- observedGeneration: helper field to see if status info is up to date with latest resource spec.
- providerAccountHost: 3scale provider account URL to which the backend is synchronized.
- state: either live or suspended depending on the
spec.suspend
bool
e.g. of a Successful status
status:
applicationID: 1
conditions:
- lastTransitionTime: '2022-11-01T14:22:14Z'
status: 'True'
type: Ready
observedGeneration: 1
providerAccountHost: 'https://3scale-admin.example.com'
state: live
Application CRD reference for more info about fields.
DeveloperAccount doesn't exist
The status.message
field will inform you if the spec.accountCR.name developerAccount is incorrect or not found
status:
conditions:
- lastTransitionTime: '2022-11-01T15:17:58Z'
message: DeveloperAccount.capabilities.3scale.net "developeraccount02" not found
status: 'False'
type: Ready
observedGeneration: 7
Product doesn't exist
The status.message
field will inform you if the product CR name is incorrect or not found
status:
conditions:
- lastTransitionTime: '2022-11-01T15:17:58Z'
message: Product.capabilities.3scale.net "product2-cr" not found
status: 'False'
type: Ready
observedGeneration: 8
ApplicationPlan doesn't exist
The status.message
field will inform you if the applicationPlanName is not found in the product CR
status:
conditions:
- lastTransitionTime: '2022-11-01T15:17:58Z'
message: >-
reconcile3scaleApplication application [testApp]: Plan [plan03] doesnt
exist in product [product1]
status: 'False'
type: Ready
observedGeneration: 9
Notes:
- 3scale applicationsAuth are a one off action i.e. a button click event.
- 3scale applicationAuth currently give access to update/generate UserKey or ApplicationKey
Consider we have the following application called example which is connected to a product and a developer account
apiVersion: capabilities.3scale.net/v1beta1
kind: Application
metadata:
name: example
spec:
accountCR:
name: developeraccount01
applicationPlanName: plan01
productCR:
name: product1-cr
name: application-name
description: description of application
You can create a secret with UserKey and ApplicationKey set to an empty string e.g. auth-secret in the 3scale-test namespace
oc create secret generic auth-secret \
--from-literal=UserKey=""\
--from-literal=ApplicationKey=""\
We can use this secret with the applicationAuth CR to generate new keys with the generateSecret bool
---
apiVersion: capabilities.3scale.net/v1beta1
kind: ApplicationAuth
metadata:
name: applicationAuth-cr1
spec:
applicationCRName: example
generateSecret: true
authSecretRef:
name: auth-secret
Once applied you will see the status.condition
update to
status:
conditions:
- lastTransitionTime: '2022-11-01T14:22:14Z'
status: 'True'
type: Ready
message: 'Application authentication has been successfully pushed, any further interactions with this CR will not be applied'
The values in the auth-secret will also be updated and note that the ApplicationID is also populated e.g.
apiVersion: v1
kind: Secret
metadata:
name: auth-secret
stringData:
UserKey: <Generated UserKey value>
ApplicationKey: <Generated ApplicationKey value>
ApplicationID: <ApplicationID value>
You can also manually create the key values e.g. auth-secret2
oc create secret generic auth-secret2 \
--from-literal=UserKey="testUserKey"\
--from-literal=ApplicationKey="testApplicationKey"\
The GenerateSecret bool is not populate for this CR
apiVersion: capabilities.3scale.net/v1beta1
kind: ApplicationAuth
metadata:
name: applicationAuth-cr2
spec:
applicationCRName: example
authSecretRef:
name: auth-secret2
The values in the auth-secret2 will remain the same and note that the ApplicationID is populated e.g.
apiVersion: v1
kind: Secret
metadata:
name: auth-secret
stringData:
UserKey: testUserKey
ApplicationKey: testApplicationKey
ApplicationID: <ApplicationID value>
ApplicationAuth CRD reference for more info about fields.
Fields:
- conditions: status.Conditions k8s common pattern. States:
- Ready: Indicates the keys have successfully updated.
- Failed: Indicates the keys have not successfully updated.
e.g. of a Successful status
status:
conditions:
- lastTransitionTime: '2022-11-01T14:22:14Z'
status: 'True'
type: Ready
message: 'Application authentication has been successfully pushed, any further interactions with this CR will not be applied'
e.g. of a Failed status
status:
conditions:
- lastTransitionTime: '2022-11-01T14:22:14Z'
status: 'True'
type: Failed
message: 'ApplicationKey or UserKey of this value already exists for this application update your authSecretRef with a new value'
Reasons for a failed state are usually an API limitation Some reasons for failure are
- Key already exist for the application
- Key length needs to be longer than five characters
- There is a 5 key limit on the ApplicationKeys
ApplicationAuth CRD reference for more info about fields.
- Single sign on (SSO) authentication for the admin portal
- Single sign on (SSO) authentication for the developers portal