Functions
Setting up and using OpenShift Serverless Functions
Abstract
Chapter 1. Getting started with functions Copy linkLink copied to clipboard!
Function lifecycle management includes creating and deploying a function, after that you can call it. Use the kn func tool to perform these operations on OpenShift Serverless.
1.1. Prerequisites for OpenShift Serverless Functions Copy linkLink copied to clipboard!
To enable the use of OpenShift Serverless Functions on your cluster, you must complete the following steps:
You have installed the OpenShift Serverless Operator and Knative Serving on your cluster.
NoteFunctions are deployed as a Knative service. If you want to use event-driven architecture with your functions, you must also install Knative Eventing.
-
You have installed the
ocCLI. -
You have the Knative (
kn) CLI installed. Installing the Knative CLI enables the use ofkn funccommands which you can use to create and manage functions. - You have installed Docker Container Engine or Podman version 3.4.7 or higher.
- You have access to an available image registry, such as the OpenShift Container Registry.
-
If you are using
Quay.ioas the image registry, you must ensure that either the repository is not private, or that you have followed the OpenShift Container Platform documentation on Allowing pods to reference images from other secured registries. - If you are using the OpenShift Container Registry, a cluster administrator must expose the registry.
1.2. Creating, deploying, and invoking a function Copy linkLink copied to clipboard!
On OpenShift Serverless, you can use the kn func to create, deploy, and call a function.
Procedure
Create a function project by running the following command:
$ kn func create -l <runtime> -t <template> <path>You get an output similar to the following example command:
$ kn func create -l typescript -t cloudevents examplefuncYou get an output similar to the following example:
Created typescript function in /home/user/demo/examplefuncNavigate to the function project directory by running the following command:
You get an output similar to the following example command:
$ cd examplefuncBuild and run the function locally by running the following command:
You get an output similar to the following example command:
$ kn func runDeploy the function to your cluster by running the following command:
$ kn func deployYou get an output similar to the following example:
Function deployed at: http://func.example.comCall the function by running the following command:
$ kn func invokeThis invokes either a locally or remotely running function. If both are running, the local one is invoked.
Chapter 2. Creating functions Copy linkLink copied to clipboard!
Before you can build and deploy a function, you must create it. You can create functions by using the Knative (kn) CLI.
2.1. Creating a function by using the Knative CLI Copy linkLink copied to clipboard!
You can specify the path, runtime, template, and image registry for a function as flags on the command line, or use the -c flag to start the interactive experience in the terminal.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI.
Procedure
Create a function project:
$ kn func create -r <repository> -l <runtime> -t <template> <path>-
Accepted runtime values include
quarkus,node,typescript,go,python,springboot, andrust. Accepted template values include
httpandcloudevents.You get an output similar to the following example:
$ kn func create -l typescript -t cloudevents examplefuncYou get an output similar to the following example:
Created typescript function in /home/user/demo/examplefunc
-
Accepted runtime values include
Specify a repository that has a custom template.
You get an output similar to the following example:
$ $ kn func create -r <templates_repository> -l node -t hello-world examplefuncReplace <templates_repository> with the repository that has the function templates.
You get an output similar to the following example:
Created node function in /home/user/demo/examplefunc
2.2. Creating a function in the web console Copy linkLink copied to clipboard!
You can create a function from a Git repository by using the OpenShift Container Platform web console.
Prerequisites
Before you can create a function by using the web console, a cluster administrator must complete the following steps:
- Install the OpenShift Serverless Operator and Knative Serving on the cluster.
- Install the OpenShift Pipelines Operator on the cluster.
Create the following pipeline tasks so that they are available for all namespaces on the cluster:
$ kn func tkn-tasks | oc apply -f -$ oc apply -f https://raw.githubusercontent.com/openshift-knative/kn-plugin-func/serverless-1.34/pkg/pipelines/resources/tekton/pipeline/dev-console/0.1/nodejs-pipeline.yaml
- You must log in to the OpenShift Container Platform web console.
- You must create a project or have access to a project with the appropriate roles and permissions to create applications and other workloads in OpenShift Container Platform.
-
You must create or have access to a Git repository that has the code for your function. The repository must contain a
func.yamlfile and use thes2ibuild strategy.
Procedure
- Navigate to +Add → Create Serverless function. The Create Serverless function page is displayed.
- Enter a Git Repo URL that points to the Git repository that has the code for your function.
In the Pipelines section:
- Select the Build, deploy and configure a Pipeline Repository radio button to create a new pipeline for your function.
- Select the Use Pipeline from this cluster radio button to connect your function to an existing pipeline in the cluster.
- Click Create.
Verification
- After you have created a function, you can view it in the Topology view.
Chapter 3. Running functions locally Copy linkLink copied to clipboard!
You can run a function locally by using the kn func tool. This can be useful, for example, for testing the function before deploying it to the cluster.
3.1. Running a function locally Copy linkLink copied to clipboard!
You can run a function locally by using the kn func run command in the current directory or by specifying a directory with the --path flag.
If you run the function for the first time, or if you change the project files, the kn func run command builds the function before running it.
You can run a function in the current directory by using the following command:
$ kn func run
You can run a function in a specific directory by specifying the path with the --path flag:
$ kn func run --path=<directory_path>
You can also force a rebuild of an existing image before running the function, even if there have been no changes to the project files, by using the --build flag:
You can run a function and trigger a build by using the --build flag:
$ kn func run --build
If you set the build flag as false, this disables building of the image, and runs the function by using the previously built image:
You can run a function without building it by using the --build=false flag:
$ kn func run --build=false
You can use the help command to learn more about kn func run command options:
$ kn func help run
Chapter 4. Deploying functions Copy linkLink copied to clipboard!
You can deploy your functions to the cluster by using the kn func tool.
4.1. Deploying a function Copy linkLink copied to clipboard!
You can deploy a function to your cluster as a Knative service by using the kn func deploy command. If you have already deployed the function, the command pushes a new container image to a container image registry and updates the Knative service.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. - You have created a project or have access to a project with the appropriate roles and permissions to create applications and other workloads in OpenShift Container Platform.
- You must have already created and initialized the function that you want to deploy.
Procedure
Deploy a function by running the following command:
$ kn func deploy [-n <namespace> -p <path> -i <image>]You get an output similar to the following example:
Function deployed at: http://func.example.com-
If you do not specify a
namespace, the command deploys the function in the current namespace. -
The command deploys the function from the current directory unless you specify a
path. - The command derives the Knative service name from the project name. You cannot change the service name by using this command.
-
If you do not specify a
You can create a serverless function with a Git repository URL by using Import from Git or Create Serverless Function in the +Add view.
Chapter 5. Building functions Copy linkLink copied to clipboard!
To run a function, you first must build the function project. This happens automatically when using the kn func run command, but you can also build a function without running it.
5.1. Building a function Copy linkLink copied to clipboard!
Before you can run a function, you must build the function project. When you run the kn func run command, the system builds the function automatically. However, you can use the kn func build command to build a function without running it, which can be useful for advanced users or debugging scenarios.
You can run the kn func build command to create an OCI container image that you can run locally on your computer or on an OpenShift Container Platform cluster. This command uses the function project name and the image registry name to construct a fully qualified image name for your function.
5.1.1. Image container types Copy linkLink copied to clipboard!
By default, kn func build creates a container image by using Red Hat Source-to-Image (S2I) technology.
You can build a function by using Red Hat Source-to-Image (S2I):
$ kn func build
5.1.2. Image registry types Copy linkLink copied to clipboard!
By default, the system stores function images in the OpenShift Container Registry.
You can build a function by using the OpenShift Container Registry:
$ kn func build
You get an output similar to the following example:
Building function image
Function image has been built, image: registry.redhat.io/example/example-function:latest
You can override using OpenShift Container Registry as the default image registry by using the --registry flag:
$ kn func build --registry quay.io/username
You get an output similar to the following example:
Building function image
Function image has been built, image: quay.io/username/example-function:latest
5.1.3. Push flag Copy linkLink copied to clipboard!
You can add the --push flag to a kn func build command to automatically push the function image after it is successfully built:
$ kn func build --push
5.1.4. Help command Copy linkLink copied to clipboard!
You can use the help command to learn more about kn func build command options:
$ kn func help build
Chapter 6. Listing existing functions Copy linkLink copied to clipboard!
You can list existing functions. You can do it using the kn func tool.
6.1. Listing existing functions Copy linkLink copied to clipboard!
You can list existing functions by running kn func list command. To list functions that you deployed as Knative services, run kn service list command.
Procedure
List existing functions by running the following command:
$ kn func list [-n <namespace> -p <path>]You get an output similar to the following example:
NAME NAMESPACE RUNTIME URL READY example-function default node http://example-function.default.apps.ci-ln-g9f36hb-d5d6b.origin-ci-int-aws.dev.rhcloud.com TrueList functions deployed as Knative services by running the following command:
$ kn service list -n <namespace>You get an output similar to the following example:
NAME URL LATEST AGE CONDITIONS READY REASON example-function http://example-function.default.apps.ci-ln-g9f36hb-d5d6b.origin-ci-int-aws.dev.rhcloud.com example-function-gzl4c 16m 3 OK / 3 True
Chapter 7. Invoking functions Copy linkLink copied to clipboard!
You can test a deployed function by invoking it. You can do it using the kn func tool.
7.1. Invoking a deployed function with a test event Copy linkLink copied to clipboard!
You can use the kn func invoke CLI command to send a test request to invoke a function either locally or on your OpenShift Container Platform cluster. You can use this command to test that a function is working and able to receive events correctly. Invoking a function locally is useful for a quick test during function development. Invoking a function on the cluster is useful for testing that is closer to the production environment.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. - You have created a project or have access to a project with the appropriate roles and permissions to create applications and other workloads in OpenShift Container Platform.
- You must have already deployed the function that you want to call.
Procedure
Start a function by running the following command:
$ kn func invoke-
The
kn func invokecommand only works when there is either a local container image currently running, or when there is a function deployed in the cluster. -
The
kn func invokecommand executes on the local directory by default, and assumes that this directory is a function project.
-
The
Chapter 8. Deleting functions Copy linkLink copied to clipboard!
You can delete a function. You can do it using the kn func tool.
8.1. Deleting a function Copy linkLink copied to clipboard!
You can delete a function by using the kn func delete command. This is useful when a function is no longer required, and can help to save resources on your cluster.
Procedure
Delete a function by running the following command:
$ kn func delete [<function_name> -n <namespace> -p <path>]-
If you do not specify the name or path of the function to delete, the system searches the current directory for a
func.yamlfile and uses it to decide which function to delete. -
If the namespace is not specified, it defaults to the
namespacevalue in thefunc.yamlfile.
-
If you do not specify the name or path of the function to delete, the system searches the current directory for a
Chapter 9. Building and deploying functions on the cluster Copy linkLink copied to clipboard!
Instead of building a function locally, you can build a function directly on the cluster. When using this workflow on a local development machine, you only need to work with the function source code. This is useful, for example, when you cannot install on-cluster function building tools, such as docker or Podman.
9.1. Building and deploying a function on the cluster Copy linkLink copied to clipboard!
You can use the Knative (kn) CLI to start a function project build and then deploy the function directly on the cluster. To build a function project in this way, the source code for your function project must exist in a Git repository branch that is accessible to your cluster.
Prerequisites
- You have installed the Red Hat OpenShift Pipelines on your cluster.
-
You have installed the OpenShift CLI (
oc). -
You have installed the Knative (
kn) CLI.
Procedure
Create a function by running the following command:
$ kn func create <function_name> -l <runtime>- Implement the business logic of your function. Then, use Git to commit and push the changes.
Deploy your function by running the following command:
$ kn func deploy --remoteIf you are not logged into the container registry referenced in your function configuration, you are prompted to give credentials for the remote container registry that hosts the function image:
You get an output similar to the following example:
🕕 Creating Pipeline resources Please provide credentials for image registry used by Pipeline. ? Server: https://index.docker.io/v1/ ? Username: my-repo ? Password: ******** Function deployed at URL: http://test-function.default.svc.cluster.local-
To update your function, commit and push new changes by using Git, then run the
kn func deploy --remotecommand again. Optional. You can configure your function to be built on the cluster after every Git push by using pipelines-as-code:
Generate the Tekton
PipelinesandPipelineRunsconfiguration for your function by running the following command:$ kn func config git setApart from generating configuration files, this command connects to the cluster and verifies the pipeline installation. By using the token, it also creates a webhook on the function repository on behalf of the user. That webhook triggers the pipeline on the cluster every time you push changes to the repository.
You need to have a valid GitHub personal access token with the repository access to use this command.
Commit and push the generated
.tekton/pipeline.yamland.tekton/pipeline-run.yamlfiles by running the following commands:$ git add .tekton/pipeline.yaml .tekton/pipeline-run.yaml $ git commit -m 'Add the Pipelines and PipelineRuns configuration' $ git push- After you make a change to your function, commit and push it. The function is rebuilt automatically by using the created pipeline.
9.2. Specifying function revision Copy linkLink copied to clipboard!
When building and deploying a function on the cluster, you must specify the location of the function code by specifying the Git repository, branch, and subdirectory within the repository. You do not need to specify the branch if you use the main branch. Similarly, you do not need to specify the subdirectory if your function is at the root of the repository. You can specify these parameters in the func.yaml configuration file, or by using flags with the kn func deploy command.
Prerequisites
- You have installed the Red Hat OpenShift Pipelines on your cluster.
-
You have installed the OpenShift (
oc) CLI. -
You have installed the Knative (
kn) CLI.
Procedure
Deploy your function:
$ kn func deploy --remote \ --git-url <repo_url> \ [--git-branch <branch>] \ [--git-dir <function_dir>]--remote-
With the
--remoteflag, the build runs remotely. git-url <repo_url>-
Substitute
<repo_url>with the URL of the Git repository. --git-branch <branch>-
Substitute
<branch>with the Git branch, tag, or commit. If using the latest commit on themainbranch, you can skip this flag. --git-dir <function_dir>-
Substitute
<function_dir>with the directory containing the function if it is different from the repository root directory.
Similar to the following example:
$ kn func deploy --remote \ --git-url https://example.com/alice/myfunc.git \ --git-branch my-feature \ --git-dir functions/example-func/
9.3. Setting custom volume size Copy linkLink copied to clipboard!
For projects that require a volume with a larger size to build, you might need to customize the persistent volume claim (PVC) when building on the cluster. The default PVC size is 256 mebibytes.
Prerequisites
- You have installed the Red Hat OpenShift Pipelines on your cluster.
-
You have installed the OpenShift (
oc) CLI. -
You have installed the Knative (
kn) CLI.
Procedure
Deploy your function with the
--pvc-sizeflag and PVC size specification by running the following command:$ kn func deploy --remote --pvc-size='2Gi'In this example, PVC is set to two gibibytes.
9.4. Testing a function in the web console Copy linkLink copied to clipboard!
You can test a deployed serverless function by invoking it in the OpenShift Container Platform web console.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on your OpenShift Container Platform cluster.
- You have logged in to the web console.
- You have created and deployed a function.
Procedure
- Navigate to Topology.
- Click a function, then click Test Serverless Function from the Actions drop-down list in the Details panel. This opens the Test Serverless Function dialog box.
In the Test Serverless Function dialog box, change the settings for your test as required:
- Choose the Format for your test. This can be either CloudEvent or HTTP.
-
The Content-Type defaults to the
Content-TypeHTTP header value. -
You can use the Advanced Settings to change the Type or Source for
CloudEventtests, or to add optional headers. - You can change the input data for the test.
- Click Test to run your test.
- After the test is complete, the Test Serverless Function dialog box displays a status code and a message that informs you whether your test was succesful.
- Click Back to perform another test, or Close to close the testing dialog box.
Chapter 10. Connecting an event source to a function Copy linkLink copied to clipboard!
When you deploy functions, the platform creates Knative services on an OpenShift Container Platform cluster. You can connect these functions to Knative Eventing components to receive incoming events.
10.1. Connect an event source to a function Copy linkLink copied to clipboard!
Functions run as Knative services on an OpenShift Container Platform cluster. When you create an event source in the OpenShift Container Platform web console, specify a deployed function to receive events from that source.
Prerequisites
- You have installed the OpenShift Serverless Operator, Knative Serving, and Knative Eventing are on your OpenShift Container Platform cluster.
- You have logged in to the web console.
- You have created a project or have access to a project with the appropriate roles and permissions to create applications and other workloads in OpenShift Container Platform.
- You have created and deployed a function.
Procedure
- Create an event source of any type, by navigating to +Add → Event Source and selecting the event source type that you want to create.
- In the Target section of the Create Event Source form view, select your function in the Resource list.
- Click Create.
Verification
- Verify that the event source exists and connects to the function by viewing the Topology page.
- Navigate to Topology.
- View the event source and click the connected function to see the function details in the right panel.
Chapter 11. Subscribing functions to CloudEvents Copy linkLink copied to clipboard!
You can subscribe a function to a set of events. This links your function to CloudEvent objects defined by your filters and enables automated responses.
11.1. Subscribing a function to CloudEvents Copy linkLink copied to clipboard!
The subscribe command connects the function to events by matching filters for CloudEvent metadata and using a Knative Broker as the source. The function then consumes events from the broker.
Prerequisites
- You have installed Knative Eventing on the cluster.
- You have configured a Knative Broker.
-
You have installed the Knative (
kn) CLI.
Procedure
Subscribe the function to events for a given broker by running the following command:
You get an output similar to the following example command:
$ kn func subscribe --filter type=com.example.Hello --source my-brokerUse the
--sourceflag to specify the broker and one or more--filterflags to specify your filters.You can also omit the
--sourceflag to use the default broker:You get an output similar to the following example command:
$ kn func subscribe --filter type=com.example --filter extension=my-extension-valueDeploy the function with Knative Triggers:
You get an output similar to the following example command:
$ kn func deployYou get an output similar to the following example:
🙌 Function image built: <registry>/hello:latest 🎯 Creating Triggers on the cluster ✅ Function deployed in namespace "default" and exposed at URL: http://hello.default.my-cluster.example.com
Chapter 12. Functions development reference guide Copy linkLink copied to clipboard!
12.1. Developing Go functions Copy linkLink copied to clipboard!
After you have created a Go function project, you can change the template files provided to add business logic to your function. This includes configuring function invocation and the returned headers and status codes.
OpenShift Serverless Functions with Go is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
12.1.1. Go function template structure Copy linkLink copied to clipboard!
When you create a Go function by using the Knative (kn) CLI, the project directory looks like a typical Go project. The only exception is the additional func.yaml configuration file, which is used for specifying the image.
Before you can develop functions, you must configure the function.
Go functions have few restrictions. The only requirements are that your project must be defined in a function module, and must export the function Handle().
Both http and event trigger functions have the same template structure:
fn
├── README.md
├── func.yaml
├── go.mod
├── go.sum
├── handle.go
└── handle_test.go
func.yaml-
The
func.yamlconfiguration file is used to decide the image name and registry. go.mod-
You can add any required dependencies to the
go.modfile, which can include additional local Go files. When the project is built for deployment, these dependencies are included in the resulting runtime container image.
$ go get gopkg.in/yaml.v2@v2.4.0
12.1.2. About invoking Go functions Copy linkLink copied to clipboard!
When you use the Knative (kn) CLI to create a function project, you can generate a project that responds to CloudEvents or simple HTTP requests. Different methods call Go functions, depending on whether an HTTP request or a CloudEvent triggers them.
12.1.2.1. Functions triggered by an HTTP request Copy linkLink copied to clipboard!
When a function receives an incoming HTTP request, the runtime calls it with a standard Go Context as the first parameter, followed by the http.ResponseWriter and http.Request parameters. You can use standard Go techniques to access the request and set the HTTP response.
The following example displays the HTTP response:
func Handle(ctx context.Context, res http.ResponseWriter, req *http.Request) {
// Read body
body, err := ioutil.ReadAll(req.Body)
defer req.Body.Close()
if err != nil {
http.Error(res, err.Error(), 500)
return
}
// Process body and function logic
// ...
}
12.1.2.2. Functions triggered by a cloud event Copy linkLink copied to clipboard!
When an incoming cloud event is received, the event is invoked by the CloudEvents Go SDK. The invocation uses the Event type as a parameter.
You can use the Go Context as an optional parameter in the function contract, as shown in the list of supported function signatures:
The following example displays supported function signatures:
Handle()
Handle() error
Handle(context.Context)
Handle(context.Context) error
Handle(cloudevents.Event)
Handle(cloudevents.Event) error
Handle(context.Context, cloudevents.Event)
Handle(context.Context, cloudevents.Event) error
Handle(cloudevents.Event) *cloudevents.Event
Handle(cloudevents.Event) (*cloudevents.Event, error)
Handle(context.Context, cloudevents.Event) *cloudevents.Event
Handle(context.Context, cloudevents.Event) (*cloudevents.Event, error)
The following example displays CloudEvent trigger:
A cloud event is received which contains a JSON string in the data property:
{
"customerId": "0123456",
"productId": "6543210"
}
To access this data, a structure must be defined which maps properties in the cloud event data, and retrieves the data from the incoming event. The following example uses the Purchase structure:
type Purchase struct {
CustomerId string `json:"customerId"`
ProductId string `json:"productId"`
}
func Handle(ctx context.Context, event cloudevents.Event) (err error) {
purchase := &Purchase{}
if err = event.DataAs(purchase); err != nil {
fmt.Fprintf(os.Stderr, "failed to parse incoming CloudEvent %s\n", err)
return
}
// ...
}
A Go encoding/json package could be used to access the cloud event directly as JSON in the form of a bytes array:
func Handle(ctx context.Context, event cloudevents.Event) {
bytes, err := json.Marshal(event)
// ...
}
12.1.3. Go function return values Copy linkLink copied to clipboard!
Functions triggered by HTTP requests can set the response directly. You can configure the function to do this by using the Go http.ResponseWriter parameter.
The following example displays HTTP response:
func Handle(ctx context.Context, res http.ResponseWriter, req *http.Request) {
// Set response
res.Header().Add("Content-Type", "text/plain")
res.Header().Add("Content-Length", "3")
res.WriteHeader(200)
_, err := fmt.Fprintf(res, "OK\n")
if err != nil {
fmt.Fprintf(os.Stderr, "error or response write: %v", err)
}
}
Functions triggered by a cloud event might return nothing, error, or CloudEvent to push events into the Knative Eventing system. In this case, you must set a unique ID, proper Source, and a Type for the cloud event. The data can be populated from a defined structure, or from a map.
The following example displays CloudEvent response:
func Handle(ctx context.Context, event cloudevents.Event) (resp *cloudevents.Event, err error) {
// ...
response := cloudevents.NewEvent()
response.SetID("example-uuid-32943bac6fea")
response.SetSource("purchase/getter")
response.SetType("purchase")
// Set the data from Purchase type
response.SetData(cloudevents.ApplicationJSON, Purchase{
CustomerId: custId,
ProductId: prodId,
})
// OR set the data directly from map
response.SetData(cloudevents.ApplicationJSON, map[string]string{"customerId": custId, "productId": prodId})
// Validate the response
resp = &response
if err = resp.Validate(); err != nil {
fmt.Printf("invalid event created. %v", err)
}
return
}
12.1.4. Testing Go functions Copy linkLink copied to clipboard!
Go functions can be tested locally on your computer. In the default project that is created when you create a function by using kn func create, there is a handle_test.go file, which has some basic tests. These tests can be extended as needed.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. -
You have created a function by using
kn func create.
Procedure
- Navigate to the test folder for your function.
Run the tests by running the following command:
$ go test
12.2. Developing Quarkus functions Copy linkLink copied to clipboard!
After you have created a Quarkus function project, you can change the template files provided to add business logic to your function. This includes configuring function invocation and the returned headers and status codes.
12.2.1. Quarkus function template structure Copy linkLink copied to clipboard!
When you create a Quarkus function by using the Knative (kn) CLI, the project directory looks similar to a typical Maven project. Additionally, the project has the func.yaml file, which is used for configuring the function.
Before you can develop functions, you must configure the function.
Both http and event trigger functions have the same template structure:
.
├── func.yaml
├── mvnw
├── mvnw.cmd
├── pom.xml
├── README.md
└── src
├── main
│ ├── java
│ │ └── functions
│ │ ├── Function.java
│ │ ├── Input.java
│ │ └── Output.java
│ └── resources
│ └── application.properties
└── test
└── java
└── functions
├── FunctionTest.java
└── NativeFunctionIT.java
func.yaml- Used to find the image name and registry.
pom.xml- The Project Object Model (POM) file has project configuration, such as information about dependencies. You can add additional dependencies by modifying this file.
Function.java-
The function project must contain a Java method annotated with
@Funq. You can place this method in theFunction.javaclass. functions- Contains simple test cases that can be used to test your function locally.
You get an output similar to the following example:
...
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.8.0</version>
<scope>test</scope>
</dependency>
</dependencies>
...
Dependencies are downloaded during the first compilation.
12.2.2. About invoking Quarkus functions Copy linkLink copied to clipboard!
You can create a Quarkus project that responds to cloud events, or one that responds to simple HTTP requests. Cloud events in Knative are transported over HTTP as a POST request, so either function type can listen and respond to incoming HTTP requests.
When an incoming request is received, Quarkus functions are invoked with an instance of a permitted type.
The following table displays function invocation options:
| Invocation method | Data type contained in the instance | Example of data |
|---|---|---|
| HTTP POST request | JSON object in the body of the request |
|
| HTTP GET request | Data in the query string |
|
|
|
JSON object in the |
|
The following example shows a function that receives and processes the customerId and productId buy data that is listed in the earlier table:
You get an output similar to the following example:
public class Functions {
@Funq
public void processPurchase(Purchase purchase) {
// process the purchase
}
}
The corresponding Purchase JavaBean class that has the purchase data looks as follows:
You get an output similar to the following example:
public class Purchase {
private long customerId;
private long productId;
// getters and setters
}
12.2.2.1. Invocation examples Copy linkLink copied to clipboard!
The following example code defines three functions named withBeans, withCloudEvent, and withBinary;
You get an output similar to the following example:
import io.quarkus.funqy.Funq;
import io.quarkus.funqy.knative.events.CloudEvent;
public class Input {
private String message;
// getters and setters
}
public class Output {
private String message;
// getters and setters
}
public class Functions {
@Funq
public Output withBeans(Input in) {
// function body
}
@Funq
public CloudEvent<Output> withCloudEvent(CloudEvent<Input> in) {
// function body
}
@Funq
public void withBinary(byte[] in) {
// function body
}
}
The withBeans function of the Functions class can be invoked by:
An HTTP POST request with a JSON body:
$ curl "http://localhost:8080/withBeans" -X POST \ -H "Content-Type: application/json" \ -d '{"message": "Hello there."}'An HTTP GET request with query parameters:
$ curl "http://localhost:8080/withBeans?message=Hello%20there." -X GETA
CloudEventobject in binary encoding:$ curl "http://localhost:8080/" -X POST \ -H "Content-Type: application/json" \ -H "Ce-SpecVersion: 1.0" \ -H "Ce-Type: withBeans" \ -H "Ce-Source: cURL" \ -H "Ce-Id: 42" \ -d '{"message": "Hello there."}'A
CloudEventobject in structured encoding:$ curl http://localhost:8080/ \ -H "Content-Type: application/cloudevents+json" \ -d '{ "data": {"message":"Hello there."}, "datacontenttype": "application/json", "id": "42", "source": "curl", "type": "withBeans", "specversion": "1.0"}'
The withCloudEvent function of the Functions class can be invoked by using a CloudEvent object, similarly to the withBeans function. However, unlike withBeans, withCloudEvent cannot be invoked with a plain HTTP request.
The withBinary function of the Functions class can be invoked by:
A
CloudEventobject in binary encoding:$ curl "http://localhost:8080/" -X POST \ -H "Content-Type: application/octet-stream" \ -H "Ce-SpecVersion: 1.0"\ -H "Ce-Type: withBinary" \ -H "Ce-Source: cURL" \ -H "Ce-Id: 42" \ --data-binary '@img.jpg'A
CloudEventobject in structured encoding:$ curl http://localhost:8080/ \ -H "Content-Type: application/cloudevents+json" \ -d "{ \"data_base64\": \"$(base64 --wrap=0 img.jpg)\", \"datacontenttype\": \"application/octet-stream\", \"id\": \"42\", \"source\": \"curl\", \"type\": \"withBinary\", \"specversion\": \"1.0\"}"
12.2.3. CloudEvent attributes Copy linkLink copied to clipboard!
If you need to read or write the attributes of a CloudEvent, such as type or subject, you can use the CloudEvent<T> generic interface and the CloudEventBuilder builder. The <T> type parameter must be one of the permitted types.
In the following example, CloudEventBuilder is used to return success or failure of processing the purchase:
public class Functions {
private boolean _processPurchase(Purchase purchase) {
// do stuff
}
public CloudEvent<Void> processPurchase(CloudEvent<Purchase> purchaseEvent) {
System.out.println("subject is: " + purchaseEvent.subject());
if (!_processPurchase(purchaseEvent.data())) {
return CloudEventBuilder.create()
.type("purchase.error")
.build();
}
return CloudEventBuilder.create()
.type("purchase.success")
.build();
}
}
12.2.4. Quarkus function return values Copy linkLink copied to clipboard!
Functions can return an instance of any type from the list of permitted types. Or, they can return the Uni<T> type, where the <T> type parameter can be of any type from the permitted types.
The Uni<T> type is useful if a function calls asynchronous APIs, because the returned object is serialized in the same format as the received object. For example:
- If a function receives an HTTP request, then the returned object is sent in the body of an HTTP response.
-
If a function receives a
CloudEventobject in binary encoding, then the returned object is sent in the data property of a binary-encodedCloudEventobject.
The following example shows a function that fetches a list of purchases:
public class Functions {
@Funq
public List<Purchase> getPurchasesByName(String name) {
// logic to retrieve purchases
}
}
- Invoking this function through an HTTP request produces an HTTP response that has a list of purchases in the body of the response.
-
Invoking this function through an incoming
CloudEventobject produces aCloudEventresponse with a list of purchases in thedataproperty.
12.2.4.1. Permitted types Copy linkLink copied to clipboard!
The input and output of a function can be any of the void, String, or byte[] types. Additionally, they can be primitive types and their wrappers, for example, int and Integer. They can also be the following complex objects: Javabeans, maps, lists, arrays, and the special CloudEvents<T> type.
Maps, lists, arrays, the <T> type parameter of the CloudEvents<T> type, and attributes of Javabeans can only be of types listed here.
Similar to the following example:
public class Functions {
public List<Integer> getIds();
public Purchase[] getPurchasesByName(String name);
public String getNameById(int id);
public Map<String,Integer> getNameIdMapping();
public void processImage(byte[] img);
}
12.2.5. Testing Quarkus functions Copy linkLink copied to clipboard!
You can test Quarkus functions locally on your computer. The default project that kn func create creates has a src/test/ directory with basic Maven tests. You can extend these tests as needed.
Prerequisites
- You have created a Quarkus function.
-
You have installed the Knative (
kn) CLI.
Procedure
- Navigate to the project folder for your function.
Run the Maven tests:
$ ./mvnw test
12.2.6. Overriding liveness and readiness probe values for Quarkus functions Copy linkLink copied to clipboard!
You can override liveness and readiness probe values for your Quarkus functions. Configure these probes to define how the platform performs health checks on the function.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. -
You have created a function by using
kn func create.
Procedure
Override the
/health/livenessand/health/readinesspaths with your own values. You can do this either by changing properties in the function source or by setting theQUARKUS_SMALLRYE_HEALTH_LIVENESS_PATHandQUARKUS_SMALLRYE_HEALTH_READINESS_PATHenvironment variables onfunc.yamlfile.To override the paths using the function source, update the path properties in the
src/main/resources/application.propertiesfile:quarkus.smallrye-health.root-path=/health quarkus.smallrye-health.liveness-path=alive quarkus.smallrye-health.readiness-path=readyquarkus.smallrye-health.root-path=/health-
The root path, which is automatically prepended to the
livenessandreadinesspaths. quarkus.smallrye-health.liveness-path=alive-
The liveness path, set to
/health/alivehere. quarkus.smallrye-health.readiness-path=ready-
The readiness path, set to
/health/readyhere.
To override the paths using environment variables, define the path variables in the
buildblock of thefunc.yamlfile:build: builder: s2i buildEnvs: - name: QUARKUS_SMALLRYE_HEALTH_LIVENESS_PATH value: alive1 - name: QUARKUS_SMALLRYE_HEALTH_READINESS_PATH value: ready2 value: alive-
The liveness path, set to
/health/alivehere. value: ready-
The readiness path, set to
/health/readyhere.
Add the new endpoints to the
func.yamlfile, so that they are properly bound to the container for the Knative service:deploy: healthEndpoints: liveness: /health/alive readiness: /health/ready
12.3. Developing Node.js functions Copy linkLink copied to clipboard!
After you have created a Node.js function project, you can change the template files provided to add business logic to your function. This includes configuring function invocation and the returned headers and status codes.
12.3.1. Node.js function template structure Copy linkLink copied to clipboard!
When you create a Node.js function by using the Knative (kn) CLI, the project directory looks like a typical Node.js project. The only exception is the additional func.yaml file, which is used to configure the function.
Before you can develop functions, you must configure the function.
Both http and event trigger functions have the same template structure:
.
├── func.yaml
├── index.js
├── package.json
├── README.md
└── test
├── integration.js
└── unit.js
func.yaml-
The
func.yamlconfiguration file is used to determine the image name and registry. index.js-
Your project must contain an
index.jsfile which exports a single function. package.json-
You are not restricted to the dependencies provided in the template
package.jsonfile. You can add additional dependencies as you would in any other Node.js project. test- Integration and unit test scripts are provided as part of the function template.
You get an output similar to the following example:
npm install --save opossum
When the project is built for deployment, these dependencies are included in the created runtime container image.
12.3.2. About invoking Node.js functions Copy linkLink copied to clipboard!
When using the Knative (kn) CLI to create a function project, you can generate a project that responds to CloudEvents, or one that responds to simple HTTP requests. CloudEvents in Knative are transported over HTTP as a POST request, so both function types listen for and respond to incoming HTTP events.
Node.js functions can be invoked with a simple HTTP request. When an incoming request is received, functions are invoked with a context object as the first parameter.
12.3.2.1. Node.js context objects Copy linkLink copied to clipboard!
Functions are invoked by providing a context object as the first parameter. This object provides access to the incoming HTTP request information.
This information includes the HTTP request method, any query strings or headers sent with the request, the HTTP version, and the request body. Incoming requests that contain a CloudEvent attach the incoming instance of the CloudEvent to the context object so that it can be accessed by using context.cloudevent.
12.3.2.1.1. Context object methods Copy linkLink copied to clipboard!
The context object has a single method, cloudEventResponse(), that accepts a data value and returns a CloudEvent.
In a Knative system, if a function deployed as a service is invoked by an event broker sending a CloudEvent, the broker examines the response. If the response is a CloudEvent, this event is handled by the broker.
The following example displays the context object method:
// Expects to receive a CloudEvent with customer data
function handle(context, customer) {
// process the customer
const processed = handle(customer);
return context.cloudEventResponse(customer)
.source('/handle')
.type('fn.process.customer')
.response();
}
12.3.2.1.2. CloudEvent data Copy linkLink copied to clipboard!
If the incoming request is a CloudEvent, any data associated with the CloudEvent is extracted from the event and provided as a second parameter. For example, if a CloudEvent is received that has a JSON string in its data property that is similar to the following:
{
"customerId": "0123456",
"productId": "6543210"
}
When invoked, the second parameter to the function, after the context object, will be a JavaScript object that has customerId and productId properties.
You get an output similar to the following example:
function handle(context, data)
The data parameter in this example is a JavaScript object that has the customerId and productId properties.
12.3.2.1.3. Arbitrary data Copy linkLink copied to clipboard!
A function can receive any data, not just CloudEvents. For example, you might want to call a function by using POST with an arbitrary object in the body:
{
"id": "12345",
"contact": {
"title": "Mr.",
"firstname": "John",
"lastname": "Smith"
}
}
In this case, you can define the function as follows:
function handle(context, customer) {
return "Hello " + customer.contact.title + " " + customer.contact.lastname;
}
Supplying the contact object to the function would then return the following output:
Hello Mr. Smith
12.3.2.1.4. Supported data types Copy linkLink copied to clipboard!
CloudEvents can contain various data types, including JSON, XML, plain text, and binary data. These data types are provided to the function in their dedicated formats:
- JSON Data: Provided as a JavaScript object.
- XML Data: Provided as an XML document.
- Plain Text: Provided as a string.
- Binary Data: Provided as a Buffer object.
12.3.2.1.5. Multiple data types in a function Copy linkLink copied to clipboard!
Ensure your function can handle different data types by checking the Content-Type header and parsing the data. For example:
function handle(context, data) {
if (context.headers['content-type'] === 'application/json') {
// handle JSON data
} else if (context.headers['content-type'] === 'application/xml') {
// handle XML data
} else {
// handle other data types
}
}
12.3.3. Node.js function return values Copy linkLink copied to clipboard!
Functions can return any valid JavaScript type or can have no return value. When a function has no return value specified, and no failure is indicated, the caller receives a 204 No Content response.
Functions can also return a CloudEvent or a Message object to push events into the Knative Eventing system. In this case, the developer is not required to understand or implement the CloudEvent messaging specification. Headers and other relevant information from the returned values are extracted and sent with the response.
You get an output similar to the following example:
function handle(context, customer) {
// process customer and return a new CloudEvent
return new CloudEvent({
source: 'customer.processor',
type: 'customer.processed'
})
}
12.3.3.1. Returning primitive types Copy linkLink copied to clipboard!
Functions can return any valid JavaScript type, including primitives such as strings, numbers, and booleans:
You get an output similar to the following example:
function handle(context) {
return "This function Works!"
}
Calling this function returns the following string:
$ curl https://myfunction.example.com
This function Works!
You get an output similar to the following example:
function handle(context) {
let somenumber = 100
return { body: somenumber }
}
Calling this function returns the following number:
$ curl https://myfunction.example.com
100
You get an output similar to the following example:
function handle(context) {
let someboolean = false
return { body: someboolean }
}
Calling this function returns the following boolean:
$ curl https://myfunction.example.com
false
Returning primitives directly without wrapping them in an object results in a 204 No Content status code with an empty body:
You get an output similar to the following example:
function handle(context) {
let someboolean = false
return someboolean
}
Calling this function returns the following:
$ http :8080
HTTP/1.1 204 No Content
Connection: keep-alive
...
12.3.3.2. Returning headers Copy linkLink copied to clipboard!
You can set a response header by adding a headers property to the return object. These headers are extracted and sent with the response to the caller.
You get an output similar to the following example:
function handle(context, customer) {
// process customer and return custom headers
// the response will be '204 No content'
return { headers: { customerid: customer.id } };
}
12.3.3.3. Returning status codes Copy linkLink copied to clipboard!
You can set a status code that is returned to the caller by adding a statusCode property to the return object:
You get an output similar to the following example:
function handle(context, customer) {
// process customer
if (customer.restricted) {
return { statusCode: 451 }
}
}
Status codes can also be set for errors that are created and thrown by the function:
You get an output similar to the following example:
function handle(context, customer) {
// process customer
if (customer.restricted) {
const err = new Error(‘Unavailable for legal reasons’);
err.statusCode = 451;
throw err;
}
}
12.3.4. Testing Node.js functions Copy linkLink copied to clipboard!
Node.js functions can be tested locally on your computer. In the default project that is created when you create a function by using kn func create, there is a test folder that has some simple unit and integration tests.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. -
You have created a function by using
kn func create.
Procedure
- Navigate to the test folder for your function.
Run the tests:
$ npm test
12.3.5. Overriding liveness and readiness probe values for Node.js functions Copy linkLink copied to clipboard!
You can override liveness and readiness probe values for your Node.js functions. You can configure health checks performed on the function.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. -
You have created a function by using
kn func create.
Procedure
-
In your function code, create the
Functionobject, which implements the following interface:
export interface Function {
init?: () => any;
shutdown?: () => any;
liveness?: HealthCheck;
readiness?: HealthCheck;
logLevel?: LogLevel;
handle: CloudEventFunction | HTTPFunction;
}
init?: () ⇒ any- The initialization function, called before the server is started. This function is optional and should be synchronous.
shutdown?: () ⇒ any;- The shutdown function, called after the server is stopped. This function is optional and should be synchronous.
liveness?: HealthCheck;- The liveness function, called to check if the server is alive. This function is optional and should return 200/OK if the server is alive.
readiness?: HealthCheck;-
The readiness function, called to check if the server is ready to accept requests. This function is optional and should return
200/OKif the server is ready. handle: CloudEventFunction | HTTPFunction;- The function to handle HTTP requests.
For example, add the following code to the index.js file:
const Function = {
handle: (context, body) => {
// The function logic goes here
return 'function called'
},
liveness: () => {
process.stdout.write('In liveness\n');
return 'ok, alive';
},
readiness: () => {
process.stdout.write('In readiness\n');
return 'ok, ready';
}
};
Function.liveness.path = '/alive';
Function.readiness.path = '/ready';
module.exports = Function;
Function.liveness.path = '/alive';-
Custom
livenessendpoint. Function.readiness.path = '/ready';-
Custom
readinessendpoint.
As an alternative to Function.liveness.path and Function.readiness.path, you can specify custom endpoints by using the LIVENESS_URL and READINESS_URL environment variables:
run:
envs:
- name: LIVENESS_URL
value: /alive
- name: READINESS_URL
value: /ready
value: /alive-
The liveness path, set to
/alivehere. value: /ready-
The readiness path, set to
/readyhere.
-
Add the new endpoints to the
func.yamlfile, so that they are properly bound to the container for the Knative service:
deploy:
healthEndpoints:
liveness: /alive
readiness: /ready
12.3.6. Node.js context object reference Copy linkLink copied to clipboard!
The context object has several properties that can be accessed by the function developer. Accessing these properties can give information about HTTP requests and write output to the cluster logs.
12.3.6.1. Log Copy linkLink copied to clipboard!
Provides a logging object that can be used to write output to the cluster logs. The log adheres to the Pino logging API.
function handle(context) {
context.log.info(“Processing customer”);
}
You can access the function by using the kn func invoke command:
You get an output similar to the following example command:
$ kn func invoke --target 'http://example.function.com'
You get an output similar to the following example:
{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"Processing customer"}
You can change the log level to one of fatal, error, warn, info, debug, trace, or silent. To do that, change the value of logLevel by using one of these values to the environment variable FUNC_LOG_LEVEL by using the config command.
12.3.6.2. query Copy linkLink copied to clipboard!
Returns the query string for the request, if any, as key-value pairs. These attributes are also found on the context object itself.
function handle(context) {
// Log the 'name' query parameter
context.log.info(context.query.name);
// Query parameters are also attached to the context
context.log.info(context.name);
}
You can access the function by using the kn func invoke command:
You get an output similar to the following example command:
$ kn func invoke --target 'http://example.com?name=tiger'
You get an output similar to the following example:
{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"tiger"}
12.3.6.3. body Copy linkLink copied to clipboard!
Returns the request body if any. If the request body contains JSON code, this will be parsed so that the attributes are directly available.
function handle(context) {
// log the incoming request body's 'hello' parameter
context.log.info(context.body.hello);
}
You can access the function by using the curl command to invoke it:
You get an output similar to the following example command:
$ kn func invoke -d '{"Hello": "world"}'
You get an output similar to the following example:
{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"world"}
12.3.6.4. headers Copy linkLink copied to clipboard!
Returns the HTTP request headers as an object.
function handle(context) {
context.log.info(context.headers["custom-header"]);
}
You can access the function by using the kn func invoke command:
You get an output similar to the following example command:
$ kn func invoke --target 'http://example.function.com'
You get an output similar to the following example:
{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"some-value"}
12.3.6.5. HTTP requests Copy linkLink copied to clipboard!
- method
- Returns the HTTP request method as a string.
- httpVersion
- Returns the HTTP version as a string.
- httpVersionMajor
- Returns the HTTP major version number as a string.
- httpVersionMinor
- Returns the HTTP minor version number as a string.
12.4. Developing TypeScript functions Copy linkLink copied to clipboard!
After you have created a TypeScript function project, you can change the template files provided to add business logic to your function. This includes configuring function invocation and the returned headers and status codes.
12.4.1. TypeScript function template structure Copy linkLink copied to clipboard!
When you create a TypeScript function by using the Knative (kn) CLI, the project directory looks like a typical TypeScript project. The only exception is the additional func.yaml file, which is used for configuring the function.
Before you can develop functions, you must configure the function.
Both http and event trigger functions have the same template structure:
.
├── func.yaml
├── package.json
├── package-lock.json
├── README.md
├── src
│ └── index.ts
├── test
│ ├── integration.ts
│ └── unit.ts
└── tsconfig.json
func.yaml-
The
func.yamlconfiguration file is used to find the image name and registry. package.json-
You are not restricted to the dependencies provided in the template
package.jsonfile. You can add additional dependencies as you would in any other TypeScript project. index.ts-
Your project must contain an
src/index.jsfile that exports a function namedhandle. test- Integration and unit test scripts are provided as part of the function template.
The following displays how to add npm dependencies:
npm install --save opossum
When the project is built for deployment, these dependencies are included in the created runtime container image.
12.4.2. About invoking TypeScript functions Copy linkLink copied to clipboard!
When you use the Knative (kn) CLI to create a function project, you can generate a project that responds to CloudEvents or simple HTTP requests. Knative sends CloudEvents over HTTP as POST requests, so both function types listen for and respond to incoming HTTP events.
You can call TypeScript functions with a simple HTTP request. When a function receives a request, the runtime calls it with a context object as the first parameter.
12.4.2.1. TypeScript context objects Copy linkLink copied to clipboard!
To call a function, pass a context object as the first parameter. Access its properties to get information about the incoming HTTP request.
The following example displayes context object:
function handle(context:Context): string
This information includes the HTTP request method, any query strings or headers sent with the request, the HTTP version, and the request body. Incoming requests that contain a CloudEvent attach the incoming instance of the CloudEvent to the context object so that it can be accessed by using context.cloudevent.
12.4.2.1.1. Context object methods Copy linkLink copied to clipboard!
The context object has a single method, cloudEventResponse(), that accepts a data value and returns a CloudEvent.
In a Knative system, if a function deployed as a service is invoked by an event broker sending a CloudEvent, the broker examines the response. If the response is a CloudEvent, this event is handled by the broker.
The following example displayes context object method:
// Expects to receive a CloudEvent with customer data
export function handle(context: Context, cloudevent?: CloudEvent): CloudEvent {
// process the customer
const customer = cloudevent.data;
const processed = processCustomer(customer);
return context.cloudEventResponse(customer)
.source('/customer/process')
.type('customer.processed')
.response();
}
12.4.2.1.2. Context types Copy linkLink copied to clipboard!
The TypeScript type definition files export the following types for use in your functions.
The following example displayes exported type definitions:
// Invokable is the expeted Function signature for user functions
export interface Invokable {
(context: Context, cloudevent?: CloudEvent): any
}
// Logger can be used for structural logging to the console
export interface Logger {
debug: (msg: any) => void,
info: (msg: any) => void,
warn: (msg: any) => void,
error: (msg: any) => void,
fatal: (msg: any) => void,
trace: (msg: any) => void,
}
// Context represents the function invocation context, and provides
// access to the event itself as well as raw HTTP objects.
export interface Context {
log: Logger;
req: IncomingMessage;
query?: Record<string, any>;
body?: Record<string, any>|string;
method: string;
headers: IncomingHttpHeaders;
httpVersion: string;
httpVersionMajor: number;
httpVersionMinor: number;
cloudevent: CloudEvent;
cloudEventResponse(data: string|object): CloudEventResponse;
}
// CloudEventResponse is a convenience class used to create
// CloudEvents on function returns
export interface CloudEventResponse {
id(id: string): CloudEventResponse;
source(source: string): CloudEventResponse;
type(type: string): CloudEventResponse;
version(version: string): CloudEventResponse;
response(): CloudEvent;
}
12.4.2.1.3. CloudEvent data Copy linkLink copied to clipboard!
If the incoming request is a CloudEvent, any data associated with the CloudEvent is extracted from the event and provided as a second parameter. For example, if a CloudEvent is received that has a JSON string in its data property that is similar to the following:
{
"customerId": "0123456",
"productId": "6543210"
}
When invoked, the second parameter to the function, after the context object, will be a JavaScript object that has customerId and productId properties.
You get an output similar to the following example signature:
function handle(context: Context, cloudevent?: CloudEvent): CloudEvent
The cloudevent parameter in this example is a JavaScript object that has the customerId and productId properties.
12.4.3. TypeScript function return values Copy linkLink copied to clipboard!
Functions can return any valid JavaScript type or can have no return value. When a function has no return value specified, and no failure is indicated, the caller receives a 204 No Content response.
Functions can also return a CloudEvent or a Message object to push events into the Knative Eventing system. In this case, the developer is not required to understand or implement the CloudEvent messaging specification. Headers and other relevant information from the returned values are extracted and sent with the response.
You get an output similar to the following example:
export const handle: Invokable = function (
context: Context,
cloudevent?: CloudEvent
): Message {
// process customer and return a new CloudEvent
const customer = cloudevent.data;
return HTTP.binary(
new CloudEvent({
source: 'customer.processor',
type: 'customer.processed'
})
);
};
12.4.3.1. Returning headers Copy linkLink copied to clipboard!
You can set a response header by adding a headers property to the return object. These headers are extracted and sent with the response to the caller.
The following example displayes response header:
export function handle(context: Context, cloudevent?: CloudEvent): Record<string, any> {
// process customer and return custom headers
const customer = cloudevent.data as Record<string, any>;
return { headers: { 'customer-id': customer.id } };
}
12.4.3.2. Returning status codes Copy linkLink copied to clipboard!
You can set a status code that is returned to the caller by adding a statusCode property to the return object:
The following example displayes status code:
export function handle(context: Context, cloudevent?: CloudEvent): Record<string, any> {
// process customer
const customer = cloudevent.data as Record<string, any>;
if (customer.restricted) {
return {
statusCode: 451
}
}
// business logic, then
return {
statusCode: 240
}
}
Status codes can also be set for errors that are created and thrown by the function:
The following example displayes error status code:
export function handle(context: Context, cloudevent?: CloudEvent): Record<string, string> {
// process customer
const customer = cloudevent.data as Record<string, any>;
if (customer.restricted) {
const err = new Error(‘Unavailable for legal reasons’);
err.statusCode = 451;
throw err;
}
}
12.4.4. Testing TypeScript functions Copy linkLink copied to clipboard!
TypeScript functions can be tested locally on your computer. In the default project that is created when you create a function by using kn func create, there is a test folder that has some simple unit and integration tests.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. -
You have created a function by using
kn func create.
Procedure
If you have not previously run tests, install the dependencies first by running the following command:
$ npm install- Navigate to the test folder for your function.
Run the tests:
$ npm test
12.4.5. Overriding liveness and readiness probe values for TypeScript functions Copy linkLink copied to clipboard!
You can override liveness and readiness probe values for your TypeScript functions. Use these probes to configure how the platform performs health checks on the function.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. -
You have created a function by using
kn func create.
Procedure
In your function code, create the
Functionobject, which implements the following interface:export interface Function { init?: () => any; shutdown?: () => any; liveness?: HealthCheck; readiness?: HealthCheck; logLevel?: LogLevel; handle: CloudEventFunction | HTTPFunction; }init?: () ⇒ any;- The initialization function, called before the server is started. This function is optional and should be synchronous.
shutdown?: () ⇒ any; <2>- The shutdown function, called after the server is stopped. This function is optional and should be synchronous.
liveness?: HealthCheck;- The liveness function, called to check if the server is alive. This function is optional and should return 200/OK if the server is alive.
readiness?: HealthCheck;- The readiness function, called to check if the server is ready to accept requests. This function is optional and should return 200/OK if the server is ready.
handle: CloudEventFunction | HTTPFunction;- The function to handle HTTP requests.
For example, add the following code to the
index.jsfile:const Function = { handle: (context, body) => { // The function logic goes here return 'function called' }, liveness: () => { process.stdout.write('In liveness\n'); return 'ok, alive'; }, readiness: () => { process.stdout.write('In readiness\n'); return 'ok, ready'; } }; Function.liveness.path = '/alive'; Function.readiness.path = '/ready'; module.exports = Function;liveness: () ⇒ {-
Custom
livenessfunction. readiness: () ⇒ {-
Custom
readinessfunction. Function.liveness.path = '/alive';-
Custom
livenessendpoint. Function.readiness.path = '/ready';-
Custom
readinessendpoint.
As an alternative to
Function.liveness.pathandFunction.readiness.path, you can specify custom endpoints by using theLIVENESS_URLandREADINESS_URLenvironment variables:run: envs: - name: LIVENESS_URL value: /alive - name: READINESS_URL value: /readyvalue: /alive-
The liveness path, set to
/alivehere. value: /ready-
The readiness path, set to
/readyhere.
Add the new endpoints to the
func.yamlfile, so that they are properly bound to the container for the Knative service:deploy: healthEndpoints: liveness: /alive readiness: /ready
12.4.6. TypeScript context object reference Copy linkLink copied to clipboard!
The context object has several properties that can be accessed by the function developer. Accessing these properties can give information about incoming HTTP requests and write output to the cluster logs.
12.4.6.1. log Copy linkLink copied to clipboard!
Provides a logging object that can be used to write output to the cluster logs. The log adheres to the Pino logging API.
You get an output similar to the following log example:
export function handle(context: Context): string {
// log the incoming request body's 'hello' parameter
if (context.body) {
context.log.info((context.body as Record<string, string>).hello);
} else {
context.log.info('No data received');
}
return 'OK';
}
You can access the function by using the kn func invoke command:
You get an output similar to the following example command:
$ kn func invoke --target 'http://example.function.com'
You get an output similar to the following example:
{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"Processing customer"}
You can change the log level to one of fatal, error, warn, info, debug, trace, or silent. To do that, change the value of logLevel by assigning one of these values to the environment variable FUNC_LOG_LEVEL by using the config command.
12.4.6.2. query Copy linkLink copied to clipboard!
Returns the query string for the request, if any, as key-value pairs. These attributes are also found on the context object itself.
You get an output similar to the following query example:
export function handle(context: Context): string {
// log the 'name' query parameter
if (context.query) {
context.log.info((context.query as Record<string, string>).name);
} else {
context.log.info('No data received');
}
return 'OK';
}
You can access the function by using the kn func invoke command:
You get an output similar to the following example command:
$ kn func invoke --target 'http://example.function.com' --data '{"name": "tiger"}'
You get an output similar to the following example:
{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"tiger"}
{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"tiger"}
12.4.6.3. body Copy linkLink copied to clipboard!
Returns the request body, if any. If the request body contains JSON code, this will be parsed so that the attributes are directly available.
You get an output similar to the following body example:
export function handle(context: Context): string {
// log the incoming request body's 'hello' parameter
if (context.body) {
context.log.info((context.body as Record<string, string>).hello);
} else {
context.log.info('No data received');
}
return 'OK';
}
You can access the function by using the kn func invoke command:
You get an output similar to the following example command:
$ kn func invoke --target 'http://example.function.com' --data '{"hello": "world"}'
You get an output similar to the following example:
{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"world"}
12.4.6.4. headers Copy linkLink copied to clipboard!
Returns the HTTP request headers as an object.
You get an output similar to the following headers example:
export function handle(context: Context): string {
// log the incoming request body's 'hello' parameter
if (context.body) {
context.log.info((context.headers as Record<string, string>)['custom-header']);
} else {
context.log.info('No data received');
}
return 'OK';
}
You can access the function by using the curl command to call it:
You get an output similar to the following example command:
$ curl -H'x-custom-header: some-value’' http://example.function.com
You get an output similar to the following example:
{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"some-value"}
12.4.6.5. HTTP requests Copy linkLink copied to clipboard!
method- Returns the HTTP request method as a string.
httpVersion- Returns the HTTP version as a string.
httpVersionMajor- Returns the HTTP major version number as a string.
httpVersionMinor- Returns the HTTP minor version number as a string.
12.5. Developing Python functions Copy linkLink copied to clipboard!
After you have created a Python function project, you can change the template files provided to add business logic to your function. This includes configuring function invocation and the returned headers and status codes.
12.5.1. Python function template structure Copy linkLink copied to clipboard!
When you create a Python function by using the Knative (kn) CLI, the project directory looks similar to a typical Python project. Python functions have very few restrictions. The only requirements are that your project contains a func.py file that contains a main() function, and a func.yaml configuration file.
Before you can develop functions, you must configure the function.
Developers are not restricted to the dependencies provided in the template requirements.txt file. Additional dependencies can be added as they would be in any other Python project. When the project is built for deployment, these dependencies will be included in the created runtime container image.
Both http and event trigger functions have the same template structure:
Template structure
fn
├── func.py
├── func.yaml
├── requirements.txt
└── test_func.py
12.5.2. About invoking Python functions Copy linkLink copied to clipboard!
You can call Python functions with a simple HTTP request. When a function receives a request, the runtime calls it with a context object as the first parameter.
The context object is a Python class with two attributes:
-
The
requestattribute is always present, and has the Flaskrequestobject. -
The second attribute,
cloud_event, is populated if the incoming request is aCloudEventobject.
Developers can access any CloudEvent data from the context object.
You get an output similar to the following example:
def main(context: Context):
"""
The context parameter contains the Flask request object and any
CloudEvent received with the request.
"""
print(f"Method: {context.request.method}")
print(f"Event data {context.cloud_event.data}")
# ... business logic here
12.5.3. Python function return values Copy linkLink copied to clipboard!
Functions can return any value supported by Flask. This is because the invocation framework proxies these values directly to the Flask server.
You get an output similar to the following example:
def main(context: Context):
body = { "message": "Howdy!" }
headers = { "content-type": "application/json" }
return body, 200, headers
Functions can set both headers and response codes as secondary and tertiary response values from function invocation.
12.5.3.1. Returning CloudEvents Copy linkLink copied to clipboard!
Developers can use the @event decorator to tell the invoker that the function return value must be converted to a CloudEvent before sending the response.
You get an output similar to the following example:
@event("event_source"="/my/function", "event_type"="my.type")
def main(context):
# business logic here
data = do_something()
# more data processing
return data
This example sends a CloudEvent as the response value, with a type of "my.type" and a source of "/my/function". The CloudEvent data property is set to the returned data variable. The event_source and event_type decorator attributes are both optional.
12.5.4. Testing Python functions Copy linkLink copied to clipboard!
You can test Python functions locally on your computer. The default project has a test_func.py file, which provides a simple unit test for functions.
The default test framework for Python functions is unittest. You can use a different test framework if you prefer.
Prerequisites
To run Python functions tests locally, you must install the required dependencies:
$ pip install -r requirements.txt
Procedure
-
Navigate to the folder for your function that has the
test_func.pyfile. Run the tests:
$ python3 test_func.py
Chapter 13. Configuring functions Copy linkLink copied to clipboard!
13.1. Accessing secrets and config maps from functions using CLI Copy linkLink copied to clipboard!
After you deploy functions to the cluster, they can access data in secrets and config maps. Mount this data as volumes or assign it to environment variables. Configure this access by using the Knative CLI or by editing the function configuration YAML file.
13.1.1. Modifying function access to secrets and config maps interactively Copy linkLink copied to clipboard!
You can use the kn func config interactive utility to manage the secrets and config maps that your function accesses. You can list, add, and remove values stored as environment variables, and list, add, and remove volumes. Control which cluster data your function can access.
To access secrets and config maps, deploy the function on the cluster. A function running locally cannot access them.
If the function cannot access a secret or config map value, the deployment fails and reports the inaccessible values.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. - You have created a function.
Procedure
Run the following command in the function project directory:
$ kn func configYou can also specify the function project directory by using the
--pathor-poption.Use the interactive interface to perform the necessary operation. For example, using the utility to list configured volumes produces an output similar to this:
$ kn func config ? What do you want to configure? Volumes ? What operation do you want to perform? List Configured Volumes mounts: - Secret "mysecret" mounted at path: "/workspace/secret" - Secret "mysecret2" mounted at path: "/workspace/secret2"This scheme shows all operations available in the interactive utility and how to go to them:
kn func config ├─> Environment variables │ ├─> Add │ │ ├─> ConfigMap: Add all key-value pairs from a config map │ │ ├─> ConfigMap: Add value from a key in a config map │ │ ├─> Secret: Add all key-value pairs from a secret │ │ └─> Secret: Add value from a key in a secret │ ├─> List: List all configured environment variables │ └─> Remove: Remove a configured environment variable └─> Volumes ├─> Add │ ├─> ConfigMap: Mount a config map as a volume │ └─> Secret: Mount a secret as a volume ├─> List: List all configured volumes └─> Remove: Remove a configured volumeOptional: Deploy the function to make the changes take effect:
$ kn func deploy -p test
13.1.2. Modifying function access to secrets and config maps interactively by using specialized commands Copy linkLink copied to clipboard!
Every time you run the kn func config utility, you need to go to the entire dialogue to select the operation you need, as shown in the earlier section. To save steps, you can directly run a specific operation by running a more specific form of the kn func config command:
To list configured environment variables:
$ kn func config envs [-p <function_project_path>]To add environment variables to the function configuration:
$ kn func config envs add [-p <function_project_path>]To remove environment variables from the function configuration:
$ kn func config envs remove [-p <function_project_path>]To list configured volumes:
$ kn func config volumes [-p <function_project_path>]To add a volume to the function configuration:
$ kn func config volumes add [-p <function_project_path>]To remove a volume from the function configuration:
$ kn func config volumes remove [-p <function_project_path>]
13.2. Configuring your function project using the func.yaml file Copy linkLink copied to clipboard!
The func.yaml file has the configuration for your function project. The kn func command uses the values in func.yaml. For example, when you run kn func build, the command uses the value in the build field. You can override these values with command-line flags or environment variables.
13.2.1. Referencing local environment variables from func.yaml fields Copy linkLink copied to clipboard!
If you want to avoid storing sensitive information such as an API key in the function configuration, you can add a reference to an environment variable available in the local environment. You can do this by modifying the envs field in the func.yaml file.
Prerequisites
- You need to have the function project created.
- The local environment needs to contain the variable that you want to reference.
Procedure
To refer to a local environment variable, use the following syntax:
{{ env:ENV_VAR }}Substitute
ENV_VARwith the name of the variable in the local environment that you want to use.For example, you might have the
API_KEYvariable available in the local environment. You can assign its value to theMY_API_KEYvariable, which you can then directly use within your function:You get an output similar to the following example:
name: test namespace: "" runtime: go ... envs: - name: MY_API_KEY value: '{{ env:API_KEY }}' ...
13.2.2. Adding annotations to functions Copy linkLink copied to clipboard!
You can add Kubernetes annotations to a deployed Serverless function. Use annotations to attach arbitrary metadata to a function, for example, a note about the function’s purpose. Add annotations to the annotations section of the func.yaml configuration file.
The function annotation feature has the following limitations:
-
After an annotation propagates to the corresponding Knative service on the cluster, you cannot remove it from the service by deleting it from the
func.yamlfile. Remove the annotation by modifying the Knative service YAML directly or by using the OpenShift Container Platform web console. -
You cannot set annotations that
Knativesets, for example, the autoscaling annotations.
13.2.3. Adding annotations to a function Copy linkLink copied to clipboard!
You can add annotations to a function. Similar to labels, annotations use a key-value map. Annotations are useful, for example, for providing metadata about a function, such as the function’s author.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. - You have created a function.
Procedure
-
Open the
func.yamlfile for your function. For every annotation that you want to add, add the following YAML to the
annotationssection:name: test namespace: "" runtime: go ... annotations: <annotation_name>: "<annotation_value>"1 - 1
- Substitute
<annotation_name>: "<annotation_value>"with your annotation.
For example, to indicate that Alice authored the function, include the following annotation:
name: test namespace: "" runtime: go ... annotations: author: "alice@example.com"- Save the configuration.
The next time you deploy the function to the cluster, the system adds the annotations to the corresponding Knative service.
13.3. Adding function access to secrets and config maps manually Copy linkLink copied to clipboard!
You can manually add configuration for accessing secrets and config maps to your function. This might be preferable to using the kn func config interactive utility and commands, for example when you have an existing configuration snippet.
13.3.1. Mounting a secret as a volume Copy linkLink copied to clipboard!
You can mount a secret as a volume. After you mount it, access it from the function as a regular file. Store data on the cluster that the function needs, for example, a list of URIs that the function accesses.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. - You have created a function.
Procedure
-
Open the
func.yamlfile for your function. For each secret you want to mount as a volume, add the following YAML to the
volumessection:name: test namespace: "" runtime: go ... volumes: - secret: mysecret path: /workspace/secret-
Substitute
mysecretwith the name of the target secret. Substitute
/workspace/secretwith the path where you want to mount the secret.For example, to mount the
addressessecret, use the following YAML:name: test namespace: "" runtime: go ... volumes: - configMap: addresses path: /workspace/secret-addresses
-
Substitute
- Save the configuration.
13.3.2. Mounting a config map as a volume Copy linkLink copied to clipboard!
You can mount a config map as a volume. After you mount it, access it from the function as a regular file. Store data on the cluster that the function needs, for example, a list of URIs that the function accesses.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. - You have created a function.
Procedure
-
Open the
func.yamlfile for your function. For each config map you want to mount as a volume, add the following YAML to the
volumessection:name: test namespace: "" runtime: go ... volumes: - configMap: myconfigmap path: /workspace/configmap-
Substitute
myconfigmapwith the name of the target config map. Substitute
/workspace/configmapwith the path where you want to mount the config map.For example, to mount the
addressesconfig map, use the following YAML:name: test namespace: "" runtime: go ... volumes: - configMap: addresses path: /workspace/configmap-addresses
-
Substitute
- Save the configuration.
13.3.3. Setting environment variable from a key value defined in a secret Copy linkLink copied to clipboard!
You can set an environment variable from a key value defined as a secret. A value previously stored in a secret can then be accessed as an environment variable by the function at runtime. This can be useful for getting access to a value stored in a secret, such as the ID of a user.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. - You have created a function.
Procedure
-
Open the
func.yamlfile for your function. For each value from a secret key-value pair that you want to assign to an environment variable, add the following YAML to the
envssection:name: test namespace: "" runtime: go ... envs: - name: EXAMPLE value: '{{ secret:mysecret:key }}'-
Substitute
EXAMPLEwith the name of the environment variable. -
Substitute
mysecretwith the name of the target secret. Substitute
keywith the key mapped to the target value.For example, to access the user ID that is stored in
userdetailssecret, use the following YAML:name: test namespace: "" runtime: go ... envs: - value: '{{ configMap:userdetailssecret:userid }}'
-
Substitute
- Save the configuration.
13.3.4. Setting environment variable from a key value defined in a config map Copy linkLink copied to clipboard!
You can set an environment variable from a key value defined as a config map. A value previously stored in a config map can then be accessed as an environment variable by the function at runtime. This can be useful for getting access to a value stored in a config map, such as the ID of a user.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. - You have created a function.
Procedure
-
Open the
func.yamlfile for your function. For each value from a config map key-value pair that you want to assign to an environment variable, add the following YAML to the
envssection:name: test namespace: "" runtime: go ... envs: - name: EXAMPLE value: '{{ configMap:myconfigmap:key }}'-
Substitute
EXAMPLEwith the name of the environment variable. -
Substitute
myconfigmapwith the name of the target config map. Substitute
keywith the key mapped to the target value.For example, to access the user ID that is stored in
userdetailsmap, use the following YAML:name: test namespace: "" runtime: go ... envs: - value: '{{ configMap:userdetailsmap:userid }}'
-
Substitute
- Save the configuration.
13.3.5. Setting environment variables from all values defined in a secret Copy linkLink copied to clipboard!
You can set an environment variable from all values defined in a secret. Values previously stored in a secret can then be accessed as environment variables by the function at runtime. This can be useful for simultaneously getting access to a collection of values stored in a secret, for example, a set of data pertaining to a user.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. - You have created a function.
Procedure
-
Open the
func.yamlfile for your function. For every secret for which you want to import all key-value pairs as environment variables, add the following YAML to the
envssection:name: test namespace: "" runtime: go ... envs: - value: '{{ secret:mysecret }}'1 - 1
- Substitute
mysecretwith the name of the target secret.
For example, to access all user data that is stored in
userdetailssecret, use the following YAML:name: test namespace: "" runtime: go ... envs: - value: '{{ configMap:userdetailssecret }}'- Save the configuration.
13.3.6. Setting environment variables from all values defined in a config map Copy linkLink copied to clipboard!
You can set an environment variable from all values defined in a config map. Values previously stored in a config map can then be accessed as environment variables by the function at runtime. This can be useful for simultaneously getting access to a collection of values stored in a config map, for example, a set of data pertaining to a user.
Prerequisites
- You have installed the OpenShift Serverless Operator and Knative Serving on the cluster.
-
You have installed the Knative (
kn) CLI. - You have created a function.
Procedure
-
Open the
func.yamlfile for your function. For every config map for which you want to import all key-value pairs as environment variables, add the following YAML to the
envssection:name: test namespace: "" runtime: go ... envs: - value: '{{ configMap:myconfigmap }}'Substitute
myconfigmapwith the name of the target config map.For example, to access all user data that is stored in
userdetailsmap, use the following YAML:name: test namespace: "" runtime: go ... envs: - value: '{{ configMap:userdetailsmap }}'- Save the file.
13.4. Configurable fields in func.yaml Copy linkLink copied to clipboard!
You can configure some of the func.yaml fields.
13.4.1. Configurable fields in func.yaml Copy linkLink copied to clipboard!
Many of the fields in func.yaml are generated automatically when you create, build, and deploy your function. However, there are also fields that you change manually to change things, such as the function name or the image name.
13.4.1.1. buildEnvs Copy linkLink copied to clipboard!
You can use the buildEnvs field to set environment variables for the build environment. Variables that you set by using buildEnvs are not available during function runtime, unlike variables set by using envs.
You can set a buildEnv variable directly from a value. In the following example, the buildEnv variable named EXAMPLE1 is directly assigned the one value:
buildEnvs:
- name: EXAMPLE1
value: one
You can also set a buildEnv variable from a local environment variable. In the following example, the buildEnv variable named EXAMPLE2 is assigned the value of the LOCAL_ENV_VAR local environment variable:
buildEnvs:
- name: EXAMPLE1
value: '{{ env:LOCAL_ENV_VAR }}'
13.4.1.2. envs Copy linkLink copied to clipboard!
The envs field enables you to set environment variables to be available to your function at runtime. You can set an environment variable in several different ways:
- Directly from a value.
- From a value assigned to a local environment variable. See the section "Referencing local environment variables from func.yaml fields" for more information.
- From a key-value pair stored in a secret or config map.
- You can also import all key-value pairs stored in a secret or config map, with keys used as names of the created environment variables.
The following examples demonstrates the different ways to set an environment variable:
name: test
namespace: ""
runtime: go
...
envs:
- name: EXAMPLE1
value: value
- name: EXAMPLE2
value: '{{ env:LOCAL_ENV_VALUE }}'
- name: EXAMPLE3
value: '{{ secret:mysecret:key }}'
- name: EXAMPLE4
value: '{{ configMap:myconfigmap:key }}'
- value: '{{ secret:mysecret2 }}'
- value: '{{ configMap:myconfigmap2 }}'
-
name: EXAMPLE1: An environment variable set directly from a value. -
name: EXAMPLE2: An environment variable set from a value assigned to a local environment variable. -
name: EXAMPLE3: An environment variable assigned from a key-value pair stored in a secret. -
name: EXAMPLE4: An environment variable assigned from a key-value pair stored in a config map. -
secret:mysecret2: A set of environment variables imported from key-value pairs of a secret. -
configMap:myconfigmap2: A set of environment variables imported from key-value pairs of a config map.
13.4.1.3. builder Copy linkLink copied to clipboard!
The builder field specifies the strategy used by the function to build the image. It accepts values of pack or s2i.
13.4.1.4. build Copy linkLink copied to clipboard!
The build field indicates how the function should be built. The value local indicates that the function is built locally on your machine. The value git indicates that the function is built on a cluster by using the values specified in the git field.
13.4.1.5. volumes Copy linkLink copied to clipboard!
You can use the volumes field to mount secrets and config maps as volumes that the function can access at the specified path, as shown in the following example:
name: test
namespace: ""
runtime: go
...
volumes:
- secret: mysecret
path: /workspace/secret
- configMap: myconfigmap
path: /workspace/configmap
-
secret: mysecret: The system mounts themysecretsecret as a volume at/workspace/secret. -
configMap: myconfigmap: The system mounts themyconfigmapconfig map as a volume at/workspace/configmap.
13.4.1.6. options Copy linkLink copied to clipboard!
You can use the options field to change Knative Service properties for the deployed function, such as autoscaling. If you do not set these options, the system uses default values.
These options are available:
scale-
min: The minimum number of replicas. Must be a non-negative integer. The default is 0. -
max: The maximum number of replicas. Must be a non-negative integer. The default is 0, which means no limit. -
metric: Defines which metric type is watched by the Autoscaler. It can be set toconcurrency, which is the default, orrps. -
target: Recommendation for when to scale up based on the number of concurrently incoming requests. Thetargetoption can be a float value greater than 0.01. The default is 100, unless theoptions.resources.limits.concurrencyis set, in which casetargetdefaults to its value. -
utilization: Percentage of concurrent requests usage allowed before scaling up. It can be a float value between 1 and 100. The default is 70.
-
resourcesrequests-
cpu: A CPU resource request for the container with deployed function. -
memory: A memory resource request for the container with deployed function.
-
limits-
cpu: A CPU resource limit for the container with deployed function. -
memory: A memory resource limit for the container with deployed function. -
concurrency: Hard Limit of concurrent requests to be processed by a single replica. It can be integer value greater than or equal to 0, default is 0 - meaning no limit.
-
This is an example configuration of the scale options:
name: test
namespace: ""
runtime: go
...
options:
scale:
min: 0
max: 10
metric: concurrency
target: 75
utilization: 75
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 1000m
memory: 256Mi
concurrency: 100
13.4.1.7. image Copy linkLink copied to clipboard!
The image field sets the image name for your function after it has been built. You can change this field. If you do, the next time you run kn func build or kn func deploy, the function image will be created with the new name.
13.4.1.8. imageDigest Copy linkLink copied to clipboard!
The imageDigest field contains the SHA256 hash of the image manifest when the function is deployed. Do not change this value.
13.4.1.9. labels Copy linkLink copied to clipboard!
The labels field enables you to set labels on a deployed function.
You can set a label directly from a value. In the following example, the label with the role key is directly assigned the value of backend:
labels:
- key: role
value: backend
You can also set a label from a local environment variable. In the following example, the label with the author key is assigned the value of the USER local environment variable:
labels:
- key: author
value: '{{ env:USER }}'
13.4.1.10. name Copy linkLink copied to clipboard!
The name field defines the name of your function. This value is used as the name of your Knative service when it is deployed. You can change this field to rename the function on next deployments.
13.4.1.11. namespace Copy linkLink copied to clipboard!
The namespace field specifies the namespace in which your function is deployed.
13.4.1.12. runtime Copy linkLink copied to clipboard!
The runtime field specifies the language runtime for your function, for example, python.