Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4b4385596 | ||
|
|
b8eb27d276 | ||
|
|
a63b8b372f | ||
|
|
380b7d1bcd | ||
|
|
5f14b9b0ae | ||
|
|
746c51901d | ||
|
|
439e7d4535 | ||
|
|
8abb0005f6 | ||
|
|
c8f4647373 | ||
|
|
5c47073518 | ||
|
|
fd1461cc98 | ||
|
|
a25c167d23 | ||
|
|
e4d42797e6 | ||
|
|
6a394889f6 | ||
|
|
59c18693fa | ||
|
|
0537c4b805 | ||
|
|
6734bfbf7b | ||
|
|
557c2ee6fc | ||
|
|
52c77c5bf5 | ||
|
|
63a2cbb417 | ||
|
|
d2f4be7a44 | ||
|
|
33f967b61b | ||
|
|
3f58247b59 | ||
|
|
45756363bc | ||
|
|
e587eca08f | ||
|
|
a720377f3c | ||
|
|
42819ba362 | ||
|
|
e56e6482b3 | ||
|
|
0d252fabcd | ||
|
|
dedeef7077 | ||
|
|
7bd3f20ad6 | ||
|
|
dc1ffa859d | ||
|
|
c63a427ca3 | ||
|
|
e4a4ec4bff | ||
|
|
7190661360 | ||
|
|
67c38f2f29 | ||
|
|
23e20115da | ||
|
|
5072a13c7c | ||
|
|
9d8a46e847 | ||
|
|
dca2915a7e | ||
|
|
bc02d159f3 |
+2
-5
@@ -38,13 +38,10 @@ minikube and its built-in docker daemon:
|
||||
$ docker build -t minikube/fission-bundle .
|
||||
```
|
||||
|
||||
Next, install fission on your kubernetes cluster:
|
||||
Next, install fission with this image on your kubernetes cluster using the helm chart:
|
||||
|
||||
```
|
||||
# To install, update fission.yaml to point to the image you just made: "minikube/fission-bundle"
|
||||
$ $EDITOR fission.yaml
|
||||
$ kubectl create -f fission.yaml
|
||||
$ kubectl create -f fission-nodeport.yaml
|
||||
$ helm install --set "image=minikube/fission-bundle,pullPolicy=IfNotPresent,analytics=false" charts/fission-all
|
||||
```
|
||||
|
||||
And if you're changing the CLI too, you can build it with:
|
||||
|
||||
@@ -24,7 +24,7 @@ Language-neutral components:
|
||||
|
||||
Language-specific components:
|
||||
|
||||
* Environment container
|
||||
* Environment container(s)
|
||||
|
||||
|
||||
Controller
|
||||
@@ -112,13 +112,13 @@ Environment Container
|
||||
---------------------
|
||||
|
||||
Environment containers run user-defined functions. Environment
|
||||
containers are language specific. They must contain an HTTP server
|
||||
and a loader for functions.
|
||||
containers are language specific. Each environment container must
|
||||
contain an HTTP server and a loader for functions.
|
||||
|
||||
Poolmgr deploys the environment container into a pod with fetcher
|
||||
(fetcher is a simple utility that can fetch an HTTP url to a file at a
|
||||
configured location). This pod forms a "generic pod", because it can
|
||||
be loaded with any function.
|
||||
be loaded with any function in that language.
|
||||
|
||||
When poolmgr needs to create a service for a function, it calls
|
||||
fetcher to fetch the function. Fetcher downloads the function into a
|
||||
@@ -134,7 +134,7 @@ Following is a diagram describe how log service works:
|
||||
|
||||

|
||||
|
||||
1. Pool manager choose a pod from pool to execute user function
|
||||
1. Pool manager chooses a pod from the pool to execute user function
|
||||
2. Pool manager makes a HTTP POST to logger helper, once helper receives
|
||||
the request it creates a symlink to container log for fluentd.
|
||||
3. Fluentd reads log from symlink and pipes to influxdb
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
## Fission API ([area-api](https://github.com/fission/fission/labels/area-api))
|
||||
|
||||
- TPR-based controller
|
||||
- CRD-based controller
|
||||
- API authentication
|
||||
- Aggregated API server
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
baseURL = "http://fission.io/docs/v0.2.1"
|
||||
baseURL = "http://fission.io/docs/0.3.0"
|
||||
languageCode = "en-us"
|
||||
title = "Fission: Serverless Functions for Kubernetes"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Fission Documentation
|
||||
|
||||
* [Installation guide](install)
|
||||
|
||||
|
||||
[Installation guide](install)
|
||||
[Upgrade guide](upgrade-from-v0.1)
|
||||
* [Upgrade guide for v0.3 to v0.4](upgrade-from-v0.3)
|
||||
|
||||
@@ -48,7 +48,7 @@ First, you'll need the helm CLI:
|
||||
|
||||
On __OS X__:
|
||||
```
|
||||
$ curl -L https://storage.googleapis.com/kubernetes-helm/helm-v2.6.1-darwin-amd64.tar.gz
|
||||
$ curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.6.1-darwin-amd64.tar.gz
|
||||
|
||||
$ tar xzf helm-v2.6.1-darwin-amd64.tar.gz
|
||||
|
||||
@@ -57,7 +57,7 @@ $ mv darwin-amd64/helm /usr/local/bin
|
||||
|
||||
On __Linux__:
|
||||
```
|
||||
$ curl -L https://storage.googleapis.com/kubernetes-helm/helm-v2.6.1-linux-amd64.tar.gz
|
||||
$ curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.6.1-linux-amd64.tar.gz
|
||||
|
||||
$ tar xzf helm-v2.6.1-linux-amd64.tar.gz
|
||||
|
||||
@@ -84,7 +84,7 @@ role-based access control.)
|
||||
#### Minikube
|
||||
|
||||
```
|
||||
$ helm install --namespace fission --set serviceType=NodePort https://github.com/fission/fission/releases/download/v0.2.1/fission-all-v0.2.1.tgz
|
||||
$ helm install --namespace fission --set serviceType=NodePort https://github.com/fission/fission/releases/download/0.3.0/fission-all-0.3.0.tgz
|
||||
```
|
||||
|
||||
The serviceType variable allows configuring the type of Kubernetes
|
||||
@@ -94,7 +94,7 @@ want to expose anything outside the cluster.
|
||||
#### Cloud hosted clusters (GKE, AWS, Azure etc.)
|
||||
|
||||
```
|
||||
$ helm install --namespace fission https://github.com/fission/fission/releases/download/v0.2.1/fission-all-v0.2.1.tgz
|
||||
$ helm install --namespace fission https://github.com/fission/fission/releases/download/0.3.0/fission-all-0.3.0.tgz
|
||||
```
|
||||
|
||||
#### Minimal version
|
||||
@@ -104,7 +104,7 @@ the NATS message queue, influxDB for logs, etc. If you want a more
|
||||
minimal setup, you can install the fission-core chart instead:
|
||||
|
||||
```
|
||||
$ helm install --namespace fission https://github.com/fission/fission/releases/download/v0.2.1/fission-core-v0.2.1.tgz
|
||||
$ helm install --namespace fission https://github.com/fission/fission/releases/download/0.3.0/fission-core-0.3.0.tgz
|
||||
```
|
||||
|
||||
### Install the Fission CLI
|
||||
@@ -114,19 +114,19 @@ $ helm install --namespace fission https://github.com/fission/fission/releases/d
|
||||
Get the CLI binary for Mac:
|
||||
|
||||
```
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/v0.2.1/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/0.3.0/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
```
|
||||
|
||||
#### Linux
|
||||
|
||||
```
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/v0.2.1/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/0.3.0/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
For Windows, you can use the linux binary on WSL. Or you can download
|
||||
this windows executable: [fission.exe](https://github.com/fission/fission/releases/download/v0.2.1/fission-cli-windows.exe)
|
||||
this windows executable: [fission.exe](https://github.com/fission/fission/releases/download/0.3.0/fission-cli-windows.exe)
|
||||
|
||||
### Set environment vars
|
||||
|
||||
@@ -159,7 +159,7 @@ svc```). Then:
|
||||
Finally, you're ready to use Fission!
|
||||
|
||||
```
|
||||
$ fission env create --name nodejs --image fission/node-env:v0.2.1
|
||||
$ fission env create --name nodejs --image fission/node-env:0.3.0
|
||||
|
||||
$ curl -LO https://raw.githubusercontent.com/fission/fission/master/examples/nodejs/hello.js
|
||||
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
---
|
||||
title: "Upgrading from Fission v0.3 to v0.4.x"
|
||||
date: 2017-11-04T03:38:29+08:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
Kubernetes ThirdPartyResources ("TPR") are replaced by
|
||||
CustomResourceDefinitions ("CRD"). TPRs have been deprecated and are
|
||||
removed in Kubernetes 1.8.
|
||||
|
||||
Since Fission stores state in TPRs, we need to migrate this state from
|
||||
TPRs to CRDs while upgrading.
|
||||
|
||||
Follow the instructions below if you're upgrading a Fission 0.2.1 or
|
||||
0.3.0 cluster to 0.4. If you're using a pre-0.2 Fission cluster, use
|
||||
the [upgrade guide from 0.1 to 0.2]() and then upgrade to 0.4.0.
|
||||
|
||||
## How to Upgrade
|
||||
|
||||
1. Get the 0.4.0-rc CLI
|
||||
2. Get the Fission state from v0.3 install
|
||||
3. Upgrade to Fission 0.4.0-rc
|
||||
4. Upgrade Kubernetes cluster version to 1.7.x or higher
|
||||
5. Remove all TPR definition (for Kubernetes 1.7.x)
|
||||
6. Restore Fission state into CRDs
|
||||
|
||||
### Get the new CLI
|
||||
|
||||
#### OS X
|
||||
|
||||
```
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0-rc/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
```
|
||||
|
||||
#### Linux
|
||||
|
||||
```
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0-rc/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
For Windows, you can use the linux binary on WSL. Or you can download
|
||||
this windows executable: [fission.exe](https://github.com/fission/fission/releases/download/0.4.0-rc/fission-cli-windows.exe)
|
||||
|
||||
### Get Fission state from v0.3 install
|
||||
|
||||
```
|
||||
fission --server <your v0.3 server> tpr2crd dump --file state.json
|
||||
```
|
||||
|
||||
You can skip the --server argument if you have the environment
|
||||
variable `$FISSION_URL` set to point at a v0.3 Fission server.
|
||||
|
||||
This will create a JSON file with all your fission state in the
|
||||
current directory.
|
||||
|
||||
### Upgrade to Fission 0.4.0-rc
|
||||
|
||||
Upgrade fission with a command similar to this:
|
||||
|
||||
```
|
||||
helm upgrade fission-all --namespace fission
|
||||
```
|
||||
|
||||
### Upgrade Kubernetes cluster version
|
||||
|
||||
Since CustomResource is only supported on Kubernetes v1.7+ and higher, please make sure
|
||||
that you upgrade to the right version that supports CustomResource.
|
||||
|
||||
### Remove all TPR definition (for Kubernetes 1.7.x)
|
||||
|
||||
** NOTICE **: This step will remove TPR definition from your kubernetes cluster. Please make sure that you dump all TPRs at the second step!
|
||||
|
||||
Though Kubernetes will migrate TPRs to CRDs automatically when TPR definition is deleted if the same name CRD exists. We still need to make sure that there is no resource gets lost during the migration. Also, since we changed the capitalization of some CRDs to CamelCase (e.g. Httptrigger -> HTTPTrigger), we need to recreate those resources by ourselves.
|
||||
|
||||
```
|
||||
fission tpr2crd delete
|
||||
```
|
||||
|
||||
### Restore your Fission state into Fission 0.4.0-rc
|
||||
|
||||
```
|
||||
fission tpr2crd restore --file state.json
|
||||
```
|
||||
|
||||
This commands needs `$FISSION_URL` set to point to new fission installation.
|
||||
|
||||
It uses the file created in the first step. It doesn't modify state.json.
|
||||
|
||||
(Note that you can run this restore on any cluster; it doesn't have the be the same kubernetes
|
||||
cluster as your old install.)
|
||||
|
||||
### Verify
|
||||
|
||||
Let's check the migration result, first run following command to check CRD established state.
|
||||
|
||||
```
|
||||
kubectl get crd -o 'custom-columns=NAME:{.metadata.name},ESTABLISHED:{.status.conditions[?(@.type=="Established")].status}'
|
||||
```
|
||||
|
||||
The output should be like this
|
||||
|
||||
```
|
||||
NAME ESTABLISHED
|
||||
environments.fission.io True
|
||||
functions.fission.io True
|
||||
httptriggers.fission.io True
|
||||
kuberneteswatchtriggers.fission.io True
|
||||
messagequeuetriggers.fission.io True
|
||||
packages.fission.io True
|
||||
timetriggers.fission.io True
|
||||
```
|
||||
|
||||
And check that CRD resources you expect are there.
|
||||
|
||||
```
|
||||
COMMAND:
|
||||
fission [resource] list
|
||||
|
||||
RESOURCES:
|
||||
environments
|
||||
functions
|
||||
httptriggers
|
||||
kuberneteswatchtriggers
|
||||
messagequeuetriggers
|
||||
packages
|
||||
timetriggers
|
||||
```
|
||||
+2
-221
@@ -1,221 +1,2 @@
|
||||
|
||||
- [Running Fission on your Cluster](#running-fission-on-your-cluster)
|
||||
* [Setup Kubernetes](#setup-kubernetes)
|
||||
+ [Install and start Kubernetes on OSX:](#install-and-start-kubernetes-on-osx)
|
||||
+ [Or, install and start Kubernetes on Linux:](#or-install-and-start-kubernetes-on-linux)
|
||||
* [Verify access to the cluster](#verify-access-to-the-cluster)
|
||||
* [Get and Run Fission: Minikube or Local cluster](#get-and-run-fission-minikube-or-local-cluster)
|
||||
* [Get and Run Fission: GKE or other Cloud](#get-and-run-fission-gke-or-other-cloud)
|
||||
* [Get and Run Fission: OpenShift](#get-and-run-fission-openshift)
|
||||
+ [Using Minishift or Local Cluster](#using-minishift-or-local-cluster)
|
||||
+ [Using other clouds](#using-other-clouds)
|
||||
* [Install the client CLI](#install-the-client-cli)
|
||||
* [Run an example](#run-an-example)
|
||||
* [Enable Persistent Function Logs (Optional)](#enable-persistent-function-logs-optional)
|
||||
* [Use the web based Fission-ui (Optional)](#use-the-web-based-fission-ui-optional)
|
||||
|
||||
## Running Fission on your Cluster
|
||||
|
||||
### Setup Kubernetes
|
||||
|
||||
You can install Kubernetes on your laptop with [minikube](https://github.com/kubernetes/minikube):
|
||||
|
||||
#### Install and start Kubernetes on OSX:
|
||||
```bash
|
||||
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin
|
||||
$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.16.0/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
|
||||
$ minikube start
|
||||
```
|
||||
|
||||
#### Or, install and start Kubernetes on Linux:
|
||||
```bash
|
||||
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin
|
||||
$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.16.0/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
|
||||
$ minikube start
|
||||
```
|
||||
|
||||
Or, you can use [Google Container Engine's](https://cloud.google.com/container-engine/) free trial to get a 3 node cluster.
|
||||
|
||||
### Verify access to the cluster
|
||||
|
||||
```
|
||||
$ kubectl version
|
||||
```
|
||||
|
||||
### Get and Run Fission: Minikube or Local cluster
|
||||
|
||||
If you're using minikube or no cloud provider, use these commands to
|
||||
set up services with NodePort. This exposes fission on ports 31313
|
||||
and 31314.
|
||||
|
||||
```
|
||||
$ kubectl create -f https://github.com/fission/fission/releases/download/nightly20170705/fission-rbac.yaml
|
||||
$ kubectl create -f https://github.com/fission/fission/releases/download/nightly20170705/fission-nodeport.yaml
|
||||
```
|
||||
|
||||
Set the FISSION_URL and FISSION_ROUTER environment variables.
|
||||
FISSION_URL is used by the fission CLI to find the server.
|
||||
FISSION_URL should be prefixed with a `http://`. (FISSION_ROUTER is
|
||||
only needed for the examples below to work.)
|
||||
|
||||
If you're using minikube, use these commands:
|
||||
|
||||
```
|
||||
$ export FISSION_URL=http://$(minikube ip):31313
|
||||
$ export FISSION_ROUTER=$(minikube ip):31314
|
||||
```
|
||||
|
||||
|
||||
### Get and Run Fission: GKE or other Cloud
|
||||
|
||||
If you're using GKE or any other cloud provider that supports the
|
||||
LoadBalancer service type, use these commands:
|
||||
|
||||
```
|
||||
$ kubectl create -f https://github.com/fission/fission/releases/download/nightly20170705/fission-rbac.yaml
|
||||
$ kubectl create -f https://github.com/fission/fission/releases/download/nightly20170705/fission-cloud.yaml
|
||||
```
|
||||
|
||||
Save the external IP addresses of controller and router services in
|
||||
FISSION_URL and FISSION_ROUTER, respectively. Wait for services to
|
||||
get IP addresses (check this with ```kubectl --namespace fission get
|
||||
svc```). Then:
|
||||
|
||||
```
|
||||
$ export FISSION_URL=http://$(kubectl --namespace fission get svc controller -o=jsonpath='{..ip}')
|
||||
$ export FISSION_ROUTER=$(kubectl --namespace fission get svc router -o=jsonpath='{..ip}')
|
||||
```
|
||||
|
||||
### Get and Run Fission: OpenShift
|
||||
|
||||
If you're using OpenShift, it's possible to run Fission on it! The
|
||||
deployment template needs to be deployed as a user with cluster-admin
|
||||
permissions (like `system:admin`), as it needs to create a
|
||||
`ClusterRole` for deploying function containers from the `fission`
|
||||
namespace/project.
|
||||
|
||||
Identically as with Kubernetes, you need to set the FISSION_URL and FISSION_ROUTER environment variables. If you're using minishift, use these commands:
|
||||
|
||||
```
|
||||
$ export FISSION_URL=http://$(minishift ip):31313¬
|
||||
$ export FISSION_ROUTER=$(minishift ip):31314¬
|
||||
```
|
||||
#### Using Minishift or Local Cluster
|
||||
|
||||
If you're using minishift or no cloud provider, use these commands to set up services with NodePort. This exposes fission on ports 31313 and 31314.
|
||||
|
||||
```
|
||||
$ oc login -u system:admin
|
||||
$ oc create -f https://github.com/fission/fission/releases/download/nightly20170705/fission-openshift.yaml
|
||||
$ oc create -f https://github.com/fission/fission/releases/download/nightly20170705/fission-nodeport.yaml
|
||||
```
|
||||
|
||||
#### Using other clouds
|
||||
|
||||
If you're using any cloud provider that supports the LoadBalancer service type, use these commands:
|
||||
|
||||
```
|
||||
$ oc login -u system:admin
|
||||
$ oc create -f https://github.com/fission/fission/releases/download/nightly20170705/fission-openshift.yaml
|
||||
$ oc create -f https://github.com/fission/fission/releases/download/nightly20170705/fission-cloud.yaml
|
||||
```
|
||||
After these steps, you should be able to run fission client as with kubernetes.
|
||||
|
||||
### Install the client CLI
|
||||
|
||||
#### Mac OS
|
||||
|
||||
Get the CLI binary for Mac:
|
||||
|
||||
```
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/nightly20170705/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
```
|
||||
|
||||
#### Linux
|
||||
|
||||
```
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/nightly20170705/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
For Windows, you can use the linux binary on WSL. Or you can download
|
||||
this windows executable: [fission.exe](https://github.com/fission/fission/releases/download/nightly20170705/fission-cli-windows.exe)
|
||||
|
||||
### Run an example
|
||||
|
||||
Finally, you're ready to use Fission!
|
||||
|
||||
```
|
||||
$ fission env create --name nodejs --image fission/node-env
|
||||
|
||||
$ curl https://raw.githubusercontent.com/fission/fission/master/examples/nodejs/hello.js > hello.js
|
||||
|
||||
$ fission function create --name hello --env nodejs --code hello.js
|
||||
|
||||
$ fission route create --method GET --url /hello --function hello
|
||||
|
||||
$ curl http://$FISSION_ROUTER/hello
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
|
||||
### Enable Persistent Function Logs (Optional)
|
||||
|
||||
Fission uses InfluxDB to store logs and fluentd to forward them from
|
||||
function pods into InfluxDB.
|
||||
|
||||
```
|
||||
$ kubectl create -f https://github.com/fission/fission/releases/download/nightly20170705/fission-logger.yaml
|
||||
```
|
||||
|
||||
That's it for the basic setup. You can now use following command to view function logs:
|
||||
|
||||
```
|
||||
$ fission function logs --name hello
|
||||
```
|
||||
|
||||
You can also list the all the pods that have hosted the function
|
||||
(including ones that aren't alive any more) and view logs for a
|
||||
particular pod:
|
||||
|
||||
```
|
||||
$ fission function pods --name hello
|
||||
|
||||
$ fission function logs --name hello --pod <pod name>
|
||||
```
|
||||
|
||||
### Use the web based Fission-ui (Optional)
|
||||
|
||||
[Fission-ui](https://github.com/fission/fission-ui) is the ui for fission maintained by the community.
|
||||
It allows users to observe and manage fission. It also provides a simple online development environment for serverless functions.
|
||||
|
||||
To setup Fission-ui with fission in k8s is simple:
|
||||
|
||||
```bash
|
||||
# Run this after fission is deployed
|
||||
$ kubectl create -f https://raw.githubusercontent.com/fission/fission-ui/master/docker/fission-ui.yaml
|
||||
```
|
||||
|
||||
Then open `http://node-ip:31319` to use Fission-ui.
|
||||
|
||||
For more infomation, please check out [Fission-ui Readme](https://github.com/fission/fission-ui/blob/master/README.md).
|
||||
|
||||
### Install NATS for message-queue based triggers (Optional)
|
||||
|
||||
Fission supports message queue triggers that allow you to invoke
|
||||
functions based on events in a queue. For now, NATS-Streaming is the
|
||||
only supported message queue.
|
||||
|
||||
You can install NATS Streaming on your Kubernetes cluster with:
|
||||
|
||||
```
|
||||
$ kubectl create -f https://github.com/fission/fission/releases/download/nightly20170705/fission-nats.yaml
|
||||
```
|
||||
|
||||
You can subscribe to a NATS Streaming queue with a command like this:
|
||||
(See `fission mqtrigger --help` for details)
|
||||
|
||||
```
|
||||
$ fission mqtrigger create --name myQueueTrigger --function processEvent --topic "myQueue.request"
|
||||
```
|
||||
These instructions are replaced by:
|
||||
http://fission.io/docs/v0.2.1/install/
|
||||
|
||||
@@ -45,8 +45,24 @@ A _function_ is a piece of code that follows the fission function
|
||||
interface.
|
||||
|
||||
An _environment_ contains the language- and runtime-specific parts of
|
||||
running a function. Fission comes with NodeJS and Python
|
||||
environments; you can also extend environments or create entirely new
|
||||
running a function.
|
||||
|
||||
The following environments are currently available:
|
||||
|
||||
| Environment | Image |
|
||||
| ------------------------------------ | ------------------------- |
|
||||
| Binary (for executables or scripts) | `fission/binary-env` |
|
||||
| Go | `fission/go-env` |
|
||||
| .NET | `fission/dotnet-env` |
|
||||
| .NET 2.0 | `fission/dotnet20-env` |
|
||||
| NodeJS (Alpine) | `fission/node-env` |
|
||||
| NodeJS (Debian) | `fission/node-env-debian` |
|
||||
| Perl | `fission/perl-env` |
|
||||
| PHP 7 | `fission/php-env` |
|
||||
| Python 3 | `fission/python-env` |
|
||||
| Ruby | `fission/ruby-env` |
|
||||
|
||||
You can also extend environments or create entirely new
|
||||
ones if you want. (An environment is essentially just a container
|
||||
with a webserver and dynamic loader.)
|
||||
|
||||
@@ -81,7 +97,7 @@ See the [examples](examples) directory for more.
|
||||
Running Fission on your Cluster
|
||||
===============================
|
||||
|
||||
See the [installation guide](INSTALL.md).
|
||||
See the [installation guide](http://fission.io/docs/v0.2.1/install/).
|
||||
|
||||
Compiling Fission
|
||||
=================
|
||||
|
||||
+6
-1
@@ -98,7 +98,12 @@ func (builder *Builder) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
srcPkgPath := filepath.Join(builder.sharedVolumePath, req.SrcPkgFilename)
|
||||
deployPkgFilename := fmt.Sprintf("%v-%v", req.SrcPkgFilename, strings.ToLower(uniuri.NewLen(6)))
|
||||
deployPkgPath := filepath.Join(builder.sharedVolumePath, deployPkgFilename)
|
||||
buildLogs, err := builder.build(req.BuildCommand, srcPkgPath, deployPkgPath)
|
||||
buildCmd := req.BuildCommand
|
||||
if len(buildCmd) == 0 {
|
||||
// use default build command
|
||||
buildCmd = "/build"
|
||||
}
|
||||
buildLogs, err := builder.build(buildCmd, srcPkgPath, deployPkgPath)
|
||||
if err != nil {
|
||||
e := errors.New(fmt.Sprintf("Error building source package: %v", err))
|
||||
http.Error(w, e.Error(), 500)
|
||||
|
||||
@@ -19,6 +19,7 @@ package client
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -32,25 +33,37 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func MakeClient(serverUrl string) *Client {
|
||||
func MakeClient(builderUrl string) *Client {
|
||||
return &Client{
|
||||
url: strings.TrimSuffix(serverUrl, "/"),
|
||||
url: strings.TrimSuffix(builderUrl, "/"),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) Build(req *builder.PackageBuildRequest) error {
|
||||
func (c *Client) Build(req *builder.PackageBuildRequest) (*builder.PackageBuildResponse, error) {
|
||||
body, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
resp, err := http.Post(c.url, "application/json", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return fission.MakeErrorFromHTTP(resp)
|
||||
return nil, fission.MakeErrorFromHTTP(resp)
|
||||
}
|
||||
return nil
|
||||
|
||||
rBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pkgBuildResp := builder.PackageBuildResponse{}
|
||||
err = json.Unmarshal([]byte(rBody), &pkgBuildResp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pkgBuildResp, nil
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
FROM alpine:3.4
|
||||
|
||||
ADD builder /
|
||||
|
||||
EXPOSE 8000
|
||||
@@ -1,2 +1,3 @@
|
||||
#!/bin/sh
|
||||
GOOS=linux GOARCH=386 go build -o builder .
|
||||
#!/bin/bash
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o builder .
|
||||
|
||||
|
||||
+1
-1
@@ -38,5 +38,5 @@ func main() {
|
||||
builder := builder.MakeBuilder(dir)
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", builder.Handler)
|
||||
http.ListenAndServe(":8000", mux)
|
||||
http.ListenAndServe(":8001", mux)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
Copyright 2017 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package buildermgr
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
type (
|
||||
BuildRequest struct {
|
||||
Package metav1.ObjectMeta `json:"package"`
|
||||
}
|
||||
|
||||
BuilderMgr struct {
|
||||
fissionClient *crd.FissionClient
|
||||
kubernetesClient *kubernetes.Clientset
|
||||
storageSvcUrl string
|
||||
namespace string
|
||||
}
|
||||
)
|
||||
|
||||
func MakeBuilderMgr(fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset, storageSvcUrl string,
|
||||
envBuilderNamespace string) *BuilderMgr {
|
||||
|
||||
envWatcher := makeEnvironmentWatcher(fissionClient, kubernetesClient, envBuilderNamespace)
|
||||
go envWatcher.watchEnvironments()
|
||||
|
||||
pkgWatcher := makePackageWatcher(fissionClient, kubernetesClient, envBuilderNamespace, storageSvcUrl)
|
||||
go pkgWatcher.watchPackages()
|
||||
|
||||
return &BuilderMgr{
|
||||
fissionClient: fissionClient,
|
||||
kubernetesClient: kubernetesClient,
|
||||
storageSvcUrl: storageSvcUrl,
|
||||
namespace: envBuilderNamespace,
|
||||
}
|
||||
}
|
||||
|
||||
func (builderMgr *BuilderMgr) build(w http.ResponseWriter, r *http.Request) {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Failed to read request: %v", err)
|
||||
log.Println(e)
|
||||
http.Error(w, e, 500)
|
||||
return
|
||||
}
|
||||
|
||||
buildReq := BuildRequest{}
|
||||
err = json.Unmarshal([]byte(body), &buildReq)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("invalid request body: %v", err)
|
||||
log.Println(e)
|
||||
http.Error(w, e, 400)
|
||||
return
|
||||
}
|
||||
|
||||
buildLogs, err := buildPackage(builderMgr.fissionClient, builderMgr.kubernetesClient,
|
||||
builderMgr.namespace, builderMgr.storageSvcUrl, buildReq)
|
||||
if err != nil {
|
||||
code, e := fission.GetHTTPError(err)
|
||||
http.Error(w, e, code)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
_, err = w.Write([]byte(buildLogs))
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Failed to reply http request: %v", err)
|
||||
log.Println(e)
|
||||
http.Error(w, e, 500)
|
||||
}
|
||||
}
|
||||
|
||||
func (builderMgr *BuilderMgr) Serve(port int) {
|
||||
r := mux.NewRouter()
|
||||
r.HandleFunc("/v1/build", builderMgr.build).Methods("POST")
|
||||
address := fmt.Sprintf(":%v", port)
|
||||
log.Printf("Start buildermgr at port %v", address)
|
||||
log.Fatal(http.ListenAndServe(address, handlers.LoggingHandler(os.Stdout, r)))
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2016 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package buildermgr
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
// Start the buildermgr service.
|
||||
func Start(port int, storageSvcUrl string, envBuilderNamespace string) error {
|
||||
fissionClient, kubernetesClient, _, err := crd.MakeFissionClient()
|
||||
if err != nil {
|
||||
log.Printf("Failed to get kubernetes client: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
api := MakeBuilderMgr(fissionClient, kubernetesClient,
|
||||
storageSvcUrl, envBuilderNamespace)
|
||||
|
||||
go api.Serve(port)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2017 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/buildermgr"
|
||||
)
|
||||
|
||||
type (
|
||||
Client struct {
|
||||
url string
|
||||
}
|
||||
)
|
||||
|
||||
func MakeClient(builderUrl string) *Client {
|
||||
return &Client{
|
||||
url: strings.TrimSuffix(builderUrl, "/") + "/v1",
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) PackageBuild(req *buildermgr.BuildRequest) ([]byte, error) {
|
||||
body, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := http.Post(c.url+"/build", "application/json", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.handleResponse(resp)
|
||||
}
|
||||
|
||||
func (c *Client) handleResponse(resp *http.Response) ([]byte, error) {
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fission.MakeErrorFromHTTP(resp)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
return body, err
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
Copyright 2017 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package buildermgr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"github.com/dchest/uniuri"
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/builder"
|
||||
builderClient "github.com/fission/fission/builder/client"
|
||||
"github.com/fission/fission/crd"
|
||||
"github.com/fission/fission/environments/fetcher"
|
||||
fetcherClient "github.com/fission/fission/environments/fetcher/client"
|
||||
)
|
||||
|
||||
// buildPackage helps to build source package into deployment package.
|
||||
// Following is steps buildPackage takes to complete the build process.
|
||||
// 1. Check package status
|
||||
// 2. Update package status to running state
|
||||
// 3. Send fetch request to fetcher to fetch source package.
|
||||
// 4. Send build request to builder to start a build.
|
||||
// 5. Send upload request to fetcher to upload deployment package.
|
||||
// 6. Update package status to succeed state
|
||||
// 7. Update package resource in package ref of functions that share the same package
|
||||
// *. Update package status to failed state,if any one of steps above failed
|
||||
func buildPackage(fissionClient *crd.FissionClient, kubernetesClient *kubernetes.Clientset,
|
||||
builderNamespace string, storageSvcUrl string, buildReq BuildRequest) (buildLogs string, err error) {
|
||||
|
||||
pkg, err := fissionClient.Packages(
|
||||
buildReq.Package.Namespace).Get(buildReq.Package.Name)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error getting function CRD info: %v", err)
|
||||
log.Println(e)
|
||||
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
|
||||
return e, fission.MakeError(500, e)
|
||||
}
|
||||
|
||||
// Only do build for pending packages
|
||||
if pkg.Status.BuildStatus != fission.BuildStatusPending {
|
||||
e := "package is not in pending state"
|
||||
log.Println(e)
|
||||
return e, fission.MakeError(400, e)
|
||||
}
|
||||
|
||||
// update package status to running state, so that
|
||||
// we can know what status a package is through cli.
|
||||
newPkgRV, err := updatePackage(fissionClient, pkg, fission.BuildStatusRunning, "", nil)
|
||||
|
||||
// Kubernetes checks resource version before applying
|
||||
// new resource config. The update operation will be
|
||||
// rejected if the resource version in metadata is lower
|
||||
// than the latest version. Set resource version with
|
||||
// latest return from updatePackage.
|
||||
pkg.Metadata.ResourceVersion = newPkgRV
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error setting package pending state: %v", err)
|
||||
log.Println(e)
|
||||
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
|
||||
return e, fission.MakeError(500, e)
|
||||
}
|
||||
|
||||
env, err := fissionClient.Environments(metav1.NamespaceDefault).Get(pkg.Spec.Environment.Name)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error getting environment CRD info: %v", err)
|
||||
log.Println(e)
|
||||
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
|
||||
return e, fission.MakeError(500, e)
|
||||
}
|
||||
|
||||
svcName := fmt.Sprintf("%v-%v.%v", env.Metadata.Name, env.Metadata.ResourceVersion, builderNamespace)
|
||||
srcPkgFilename := fmt.Sprintf("%v-%v", pkg.Metadata.Name, strings.ToLower(uniuri.NewLen(6)))
|
||||
fetcherC := fetcherClient.MakeClient(fmt.Sprintf("http://%v:8000", svcName))
|
||||
builderC := builderClient.MakeClient(fmt.Sprintf("http://%v:8001", svcName))
|
||||
|
||||
fetchReq := &fetcher.FetchRequest{
|
||||
FetchType: fetcher.FETCH_SOURCE,
|
||||
Package: pkg.Metadata,
|
||||
Filename: srcPkgFilename,
|
||||
}
|
||||
|
||||
// send fetch request to fetcher
|
||||
err = fetcherC.Fetch(fetchReq)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error fetching source package: %v", err)
|
||||
log.Println(e)
|
||||
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
|
||||
return e, fission.MakeError(500, e)
|
||||
}
|
||||
|
||||
pkgBuildReq := &builder.PackageBuildRequest{
|
||||
SrcPkgFilename: srcPkgFilename,
|
||||
BuildCommand: pkg.Spec.BuildCommand,
|
||||
}
|
||||
|
||||
log.Printf("Start building with source package: %v", srcPkgFilename)
|
||||
// send build request to builder
|
||||
buildResp, err := builderC.Build(pkgBuildReq)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error building deployment package: %v", err)
|
||||
log.Println(e)
|
||||
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
|
||||
return e, fission.MakeError(500, e)
|
||||
}
|
||||
|
||||
log.Printf("Build succeed, source package: %v, deployment package: %v", srcPkgFilename, buildResp.ArtifactFilename)
|
||||
|
||||
uploadReq := &fetcher.UploadRequest{
|
||||
Filename: buildResp.ArtifactFilename,
|
||||
StorageSvcUrl: storageSvcUrl,
|
||||
}
|
||||
|
||||
log.Printf("Start uploading deployment package: %v", buildResp.ArtifactFilename)
|
||||
// ask fetcher to upload the deployment package
|
||||
uploadResp, err := fetcherC.Upload(uploadReq)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error uploading deployment package: %v", err)
|
||||
log.Println(e)
|
||||
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
|
||||
return e, fission.MakeError(500, e)
|
||||
}
|
||||
|
||||
log.Printf("Start updating info of package: %v", pkg.Metadata.Name)
|
||||
// update package status and also build logs
|
||||
newPkgRV, err = updatePackage(fissionClient, pkg,
|
||||
fission.BuildStatusSucceeded, buildResp.BuildLogs, uploadResp)
|
||||
pkg.Metadata.ResourceVersion = newPkgRV
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error creating deployment package CRD resource: %v", err)
|
||||
log.Println(e)
|
||||
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
|
||||
return e, fission.MakeError(500, e)
|
||||
}
|
||||
|
||||
fnList, err := fissionClient.
|
||||
Functions(metav1.NamespaceDefault).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error getting function list: %v", err)
|
||||
log.Println(e)
|
||||
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
|
||||
return e, fission.MakeError(500, e)
|
||||
}
|
||||
|
||||
// A package may be used by multiple functions. Update
|
||||
// functions with old package resource version
|
||||
for _, fn := range fnList.Items {
|
||||
if fn.Spec.Package.PackageRef.Name == pkg.Metadata.Name &&
|
||||
fn.Spec.Package.PackageRef.Namespace == pkg.Metadata.Namespace &&
|
||||
fn.Spec.Package.PackageRef.ResourceVersion != pkg.Metadata.ResourceVersion {
|
||||
fn.Spec.Package.PackageRef.ResourceVersion = newPkgRV
|
||||
// update CRD
|
||||
_, err = fissionClient.Functions(fn.Metadata.Namespace).Update(&fn)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error updating function package resource version: %v", err)
|
||||
log.Println(e)
|
||||
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
|
||||
return e, fission.MakeError(500, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Completed build request for package: %v", pkg.Metadata.Name)
|
||||
|
||||
return buildResp.BuildLogs, nil
|
||||
}
|
||||
|
||||
func updatePackage(fissionClient *crd.FissionClient,
|
||||
pkg *crd.Package, status fission.BuildStatus, buildLogs string,
|
||||
uploadResp *fetcher.UploadResponse) (string, error) {
|
||||
|
||||
pkg.Status = fission.PackageStatus{
|
||||
BuildStatus: status,
|
||||
BuildLog: buildLogs,
|
||||
}
|
||||
|
||||
if uploadResp != nil {
|
||||
pkg.Spec.Deployment = fission.Archive{
|
||||
Type: fission.ArchiveTypeUrl,
|
||||
URL: uploadResp.ArchiveDownloadUrl,
|
||||
Checksum: uploadResp.Checksum,
|
||||
}
|
||||
}
|
||||
|
||||
// update package spec
|
||||
pkg, err := fissionClient.Packages(metav1.NamespaceDefault).Update(pkg)
|
||||
if err != nil {
|
||||
log.Printf("Error updating package: %v", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
// return resource version for function to update function package ref
|
||||
return pkg.Metadata.ResourceVersion, nil
|
||||
}
|
||||
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
Copyright 2017 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package buildermgr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
type requestType int
|
||||
|
||||
const (
|
||||
GET_BUILDER requestType = iota
|
||||
CLEANUP_BUILDERS
|
||||
|
||||
LABEL_ENV_NAME = "envName"
|
||||
LABEL_ENV_RESOURCEVERSION = "envResourceVersion"
|
||||
)
|
||||
|
||||
type (
|
||||
builderInfo struct {
|
||||
envMetadata *metav1.ObjectMeta
|
||||
deployment *v1beta1.Deployment
|
||||
service *apiv1.Service
|
||||
}
|
||||
|
||||
envwRequest struct {
|
||||
requestType
|
||||
env *crd.Environment
|
||||
envList []crd.Environment
|
||||
respChan chan envwResponse
|
||||
}
|
||||
|
||||
envwResponse struct {
|
||||
builderInfo *builderInfo
|
||||
err error
|
||||
}
|
||||
|
||||
environmentWatcher struct {
|
||||
cache map[string]*builderInfo
|
||||
requestChan chan envwRequest
|
||||
builderNamespace string
|
||||
fissionClient *crd.FissionClient
|
||||
kubernetesClient *kubernetes.Clientset
|
||||
fetcherImage string
|
||||
fetcherImagePullPolicy apiv1.PullPolicy
|
||||
}
|
||||
)
|
||||
|
||||
func makeEnvironmentWatcher(fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset, builderNamespace string) *environmentWatcher {
|
||||
|
||||
fetcherImage := os.Getenv("FETCHER_IMAGE")
|
||||
if len(fetcherImage) == 0 {
|
||||
fetcherImage = "fission/fetcher"
|
||||
}
|
||||
|
||||
fetcherImagePullPolicy := os.Getenv("FETCHER_IMAGE_PULL_POLICY")
|
||||
if len(fetcherImagePullPolicy) == 0 {
|
||||
fetcherImagePullPolicy = "IfNotPresent"
|
||||
}
|
||||
|
||||
var pullPolicy apiv1.PullPolicy
|
||||
switch fetcherImagePullPolicy {
|
||||
case "Always":
|
||||
pullPolicy = apiv1.PullAlways
|
||||
case "Never":
|
||||
pullPolicy = apiv1.PullNever
|
||||
default:
|
||||
pullPolicy = apiv1.PullIfNotPresent
|
||||
}
|
||||
|
||||
envWatcher := &environmentWatcher{
|
||||
cache: make(map[string]*builderInfo),
|
||||
requestChan: make(chan envwRequest),
|
||||
builderNamespace: builderNamespace,
|
||||
fissionClient: fissionClient,
|
||||
kubernetesClient: kubernetesClient,
|
||||
fetcherImage: fetcherImage,
|
||||
fetcherImagePullPolicy: pullPolicy,
|
||||
}
|
||||
|
||||
go envWatcher.service()
|
||||
|
||||
return envWatcher
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) getCacheKey(envName string, envResourceVersion string) string {
|
||||
return fmt.Sprintf("%v-%v", envName, envResourceVersion)
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) getLabels(envName string, envResourceVersion string) map[string]string {
|
||||
return map[string]string{
|
||||
LABEL_ENV_NAME: envName,
|
||||
LABEL_ENV_RESOURCEVERSION: envResourceVersion,
|
||||
}
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) watchEnvironments() {
|
||||
rv := ""
|
||||
for {
|
||||
wi, err := envw.fissionClient.Environments(metav1.NamespaceAll).Watch(metav1.ListOptions{
|
||||
ResourceVersion: rv,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Error watching environment list: %v", err)
|
||||
}
|
||||
|
||||
for {
|
||||
ev, more := <-wi.ResultChan()
|
||||
if !more {
|
||||
// restart watch from last rv
|
||||
break
|
||||
}
|
||||
if ev.Type == watch.Error {
|
||||
// restart watch from the start
|
||||
rv = ""
|
||||
time.Sleep(time.Second)
|
||||
break
|
||||
}
|
||||
env := ev.Object.(*crd.Environment)
|
||||
rv = env.Metadata.ResourceVersion
|
||||
envw.sync()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) sync() {
|
||||
envList, err := envw.fissionClient.Environments(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
log.Fatalf("Error syncing environment CRD resources: %v", err)
|
||||
}
|
||||
|
||||
// Create environment builders for all environments
|
||||
for i := range envList.Items {
|
||||
env := envList.Items[i]
|
||||
|
||||
if env.Spec.Version == 1 || // builder is not supported with v1 interface
|
||||
len(env.Spec.Builder.Image) == 0 { // ignore env without builder image
|
||||
continue
|
||||
}
|
||||
_, err := envw.getEnvBuilder(&env)
|
||||
if err != nil {
|
||||
log.Printf("Error creating builder for %v: %v", env.Metadata.Name, err)
|
||||
}
|
||||
}
|
||||
envw.cleanupEnvBuilders(envList.Items)
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) service() {
|
||||
for {
|
||||
req := <-envw.requestChan
|
||||
switch req.requestType {
|
||||
case GET_BUILDER:
|
||||
key := envw.getCacheKey(req.env.Metadata.Name, req.env.Metadata.ResourceVersion)
|
||||
builderInfo, ok := envw.cache[key]
|
||||
if !ok {
|
||||
builderInfo, err := envw.createBuilder(req.env)
|
||||
if err != nil {
|
||||
req.respChan <- envwResponse{err: err}
|
||||
continue
|
||||
}
|
||||
envw.cache[key] = builderInfo
|
||||
}
|
||||
req.respChan <- envwResponse{builderInfo: builderInfo}
|
||||
|
||||
case CLEANUP_BUILDERS:
|
||||
latestEnvList := make(map[string]*crd.Environment)
|
||||
for i := range req.envList {
|
||||
env := req.envList[i]
|
||||
key := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion)
|
||||
latestEnvList[key] = &env
|
||||
}
|
||||
|
||||
// If an environment is deleted when builder manager down,
|
||||
// the builder belongs to the environment will be out-of-
|
||||
// control (an orphan builder) since there is no record in
|
||||
// cache and CRD. We need to iterate over the services &
|
||||
// deployments to remove both normal and orphan builders.
|
||||
|
||||
svcList, err := envw.getBuilderServiceList(nil)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
for _, svc := range svcList {
|
||||
envName := svc.ObjectMeta.Labels[LABEL_ENV_NAME]
|
||||
envResourceVersion := svc.ObjectMeta.Labels[LABEL_ENV_RESOURCEVERSION]
|
||||
key := envw.getCacheKey(envName, envResourceVersion)
|
||||
if _, ok := latestEnvList[key]; !ok {
|
||||
err := envw.deleteBuilderService(svc.ObjectMeta.Labels)
|
||||
if err != nil {
|
||||
log.Printf("Error removing builder service: %v", err)
|
||||
}
|
||||
}
|
||||
delete(envw.cache, svc.ObjectMeta.Name)
|
||||
}
|
||||
|
||||
deployList, err := envw.getBuilderDeploymentList(nil)
|
||||
if err != nil {
|
||||
log.Printf(err.Error())
|
||||
}
|
||||
for _, deploy := range deployList {
|
||||
envName := deploy.ObjectMeta.Labels[LABEL_ENV_NAME]
|
||||
envResourceVersion := deploy.ObjectMeta.Labels[LABEL_ENV_RESOURCEVERSION]
|
||||
key := envw.getCacheKey(envName, envResourceVersion)
|
||||
if _, ok := latestEnvList[key]; !ok {
|
||||
err := envw.deleteBuilderDeployment(deploy.ObjectMeta.Labels)
|
||||
if err != nil {
|
||||
log.Printf("Error removing builder deployment: %v", err)
|
||||
}
|
||||
}
|
||||
delete(envw.cache, deploy.ObjectMeta.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) getEnvBuilder(env *crd.Environment) (*builderInfo, error) {
|
||||
respChan := make(chan envwResponse)
|
||||
envw.requestChan <- envwRequest{
|
||||
requestType: GET_BUILDER,
|
||||
env: env,
|
||||
respChan: respChan,
|
||||
}
|
||||
resp := <-respChan
|
||||
return resp.builderInfo, resp.err
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) cleanupEnvBuilders(envs []crd.Environment) {
|
||||
envw.requestChan <- envwRequest{
|
||||
requestType: CLEANUP_BUILDERS,
|
||||
envList: envs,
|
||||
}
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) createBuilder(env *crd.Environment) (*builderInfo, error) {
|
||||
var svc *apiv1.Service
|
||||
var deploy *v1beta1.Deployment
|
||||
|
||||
sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion)
|
||||
|
||||
svcList, err := envw.getBuilderServiceList(sel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// there should be only one service in svcList
|
||||
if len(svcList) == 0 {
|
||||
svc, err = envw.createBuilderService(env)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating builder service: %v", err)
|
||||
}
|
||||
} else if len(svcList) == 1 {
|
||||
svc = &svcList[0]
|
||||
} else {
|
||||
return nil, fmt.Errorf("Found more than one builder service for environment %v", env.Metadata.Name)
|
||||
}
|
||||
|
||||
deployList, err := envw.getBuilderDeploymentList(sel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// there should be only one deploy in deployList
|
||||
if len(deployList) == 0 {
|
||||
deploy, err = envw.createBuilderDeployment(env)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating builder deployment: %v", err)
|
||||
}
|
||||
} else if len(deployList) == 1 {
|
||||
deploy = &deployList[0]
|
||||
} else {
|
||||
return nil, fmt.Errorf("Found more than one builder deployment for environment %v", env.Metadata.Name)
|
||||
}
|
||||
|
||||
return &builderInfo{
|
||||
envMetadata: &env.Metadata,
|
||||
service: svc,
|
||||
deployment: deploy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) deleteBuilderService(sel map[string]string) error {
|
||||
svcList, err := envw.getBuilderServiceList(sel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, svc := range svcList {
|
||||
log.Printf("Removing builder service: %v", svc.ObjectMeta.Name)
|
||||
|
||||
// cascading deletion
|
||||
// https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/
|
||||
falseVal := false
|
||||
delOpt := &metav1.DeleteOptions{
|
||||
OrphanDependents: &falseVal,
|
||||
}
|
||||
|
||||
err = envw.kubernetesClient.
|
||||
Services(envw.builderNamespace).
|
||||
Delete(svc.ObjectMeta.Name, delOpt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting builder service: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) deleteBuilderDeployment(sel map[string]string) error {
|
||||
deployList, err := envw.getBuilderDeploymentList(sel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, deploy := range deployList {
|
||||
log.Printf("Removing builder deployment: %v", deploy.ObjectMeta.Name)
|
||||
|
||||
falseVal := false
|
||||
delOpt := &metav1.DeleteOptions{
|
||||
OrphanDependents: &falseVal,
|
||||
}
|
||||
|
||||
err = envw.kubernetesClient.ExtensionsV1beta1().
|
||||
Deployments(envw.builderNamespace).
|
||||
Delete(deploy.ObjectMeta.Name, delOpt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleteing builder deployment: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) getBuilderServiceList(sel map[string]string) ([]apiv1.Service, error) {
|
||||
svcList, err := envw.kubernetesClient.Services(envw.builderNamespace).List(
|
||||
metav1.ListOptions{
|
||||
LabelSelector: labels.Set(sel).AsSelector().String(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting builder service list: %v", err)
|
||||
}
|
||||
return svcList.Items, nil
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) createBuilderService(env *crd.Environment) (*apiv1.Service, error) {
|
||||
name := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion)
|
||||
sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion)
|
||||
service := apiv1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: envw.builderNamespace,
|
||||
Name: name,
|
||||
Labels: sel,
|
||||
},
|
||||
Spec: apiv1.ServiceSpec{
|
||||
Selector: sel,
|
||||
Type: apiv1.ServiceTypeClusterIP,
|
||||
Ports: []apiv1.ServicePort{
|
||||
{
|
||||
Name: "fetcher-port",
|
||||
Protocol: apiv1.ProtocolTCP,
|
||||
Port: 8000,
|
||||
TargetPort: intstr.IntOrString{
|
||||
Type: intstr.Int,
|
||||
IntVal: 8000,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "builder-port",
|
||||
Protocol: apiv1.ProtocolTCP,
|
||||
Port: 8001,
|
||||
TargetPort: intstr.IntOrString{
|
||||
Type: intstr.Int,
|
||||
IntVal: 8001,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
log.Printf("Creating builder service: %v", name)
|
||||
_, err := envw.kubernetesClient.Services(envw.builderNamespace).Create(&service)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &service, nil
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) getBuilderDeploymentList(sel map[string]string) ([]v1beta1.Deployment, error) {
|
||||
deployList, err := envw.kubernetesClient.ExtensionsV1beta1().Deployments(envw.builderNamespace).List(
|
||||
metav1.ListOptions{
|
||||
LabelSelector: labels.Set(sel).AsSelector().String(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting builder deployment list: %v", err)
|
||||
}
|
||||
return deployList.Items, nil
|
||||
}
|
||||
|
||||
func (envw *environmentWatcher) createBuilderDeployment(env *crd.Environment) (*v1beta1.Deployment, error) {
|
||||
sharedMountPath := "/package"
|
||||
name := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion)
|
||||
sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion)
|
||||
var replicas int32 = 1
|
||||
deployment := &v1beta1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: envw.builderNamespace,
|
||||
Name: name,
|
||||
Labels: sel,
|
||||
},
|
||||
Spec: v1beta1.DeploymentSpec{
|
||||
Replicas: &replicas,
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: sel,
|
||||
},
|
||||
Template: apiv1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: sel,
|
||||
},
|
||||
Spec: apiv1.PodSpec{
|
||||
Volumes: []apiv1.Volume{
|
||||
{
|
||||
Name: "package",
|
||||
VolumeSource: apiv1.VolumeSource{
|
||||
EmptyDir: &apiv1.EmptyDirVolumeSource{},
|
||||
},
|
||||
},
|
||||
},
|
||||
Containers: []apiv1.Container{
|
||||
{
|
||||
Name: "builder",
|
||||
Image: env.Spec.Builder.Image,
|
||||
ImagePullPolicy: apiv1.PullAlways,
|
||||
TerminationMessagePath: "/dev/termination-log",
|
||||
VolumeMounts: []apiv1.VolumeMount{
|
||||
{
|
||||
Name: "package",
|
||||
MountPath: sharedMountPath,
|
||||
},
|
||||
},
|
||||
Command: []string{"/builder", sharedMountPath},
|
||||
},
|
||||
{
|
||||
Name: "fetcher",
|
||||
Image: envw.fetcherImage,
|
||||
ImagePullPolicy: envw.fetcherImagePullPolicy,
|
||||
TerminationMessagePath: "/dev/termination-log",
|
||||
VolumeMounts: []apiv1.VolumeMount{
|
||||
{
|
||||
Name: "package",
|
||||
MountPath: sharedMountPath,
|
||||
},
|
||||
},
|
||||
Command: []string{"/fetcher", sharedMountPath},
|
||||
},
|
||||
},
|
||||
ServiceAccountName: "fission-builder",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
log.Printf("Creating builder deployment: %v", envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion))
|
||||
_, err := envw.kubernetesClient.ExtensionsV1beta1().Deployments(envw.builderNamespace).Create(deployment)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return deployment, nil
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright 2017 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package buildermgr
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
type (
|
||||
packageWatcher struct {
|
||||
fissionClient *crd.FissionClient
|
||||
kubernetesClient *kubernetes.Clientset
|
||||
builderNamespace string
|
||||
storageSvcUrl string
|
||||
}
|
||||
)
|
||||
|
||||
func makePackageWatcher(fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset, builderNamespace string, storageSvcUrl string) *packageWatcher {
|
||||
pkgw := &packageWatcher{
|
||||
fissionClient: fissionClient,
|
||||
kubernetesClient: kubernetesClient,
|
||||
builderNamespace: builderNamespace,
|
||||
storageSvcUrl: storageSvcUrl,
|
||||
}
|
||||
return pkgw
|
||||
}
|
||||
|
||||
func (pkgw *packageWatcher) build(pkgMetadata metav1.ObjectMeta) {
|
||||
buildReq := BuildRequest{
|
||||
Package: pkgMetadata,
|
||||
}
|
||||
_, err := buildPackage(pkgw.fissionClient,
|
||||
pkgw.kubernetesClient, pkgw.builderNamespace, pkgw.storageSvcUrl, buildReq)
|
||||
if err != nil {
|
||||
log.Printf("Error building package %v: %v", buildReq.Package.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (pkgw *packageWatcher) watchPackages() {
|
||||
rv := ""
|
||||
for {
|
||||
wi, err := pkgw.fissionClient.Packages(metav1.NamespaceDefault).Watch(metav1.ListOptions{
|
||||
ResourceVersion: rv,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Error watching package CRD resources: %v", err)
|
||||
}
|
||||
|
||||
for {
|
||||
ev, more := <-wi.ResultChan()
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
if ev.Type == watch.Error {
|
||||
rv = ""
|
||||
time.Sleep(time.Second)
|
||||
break
|
||||
}
|
||||
pkg := ev.Object.(*crd.Package)
|
||||
rv = pkg.Metadata.ResourceVersion
|
||||
|
||||
// only do build for packages in pending state
|
||||
if pkg.Status.BuildStatus == fission.BuildStatusPending {
|
||||
go pkgw.build(pkg.Metadata)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+1
-2
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
package cache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -114,7 +113,7 @@ func (c *Cache) service() {
|
||||
val := c.cache[req.key]
|
||||
val.atime = time.Now()
|
||||
resp.existingValue = val.value
|
||||
resp.error = errors.New("value already exists")
|
||||
resp.error = fission.MakeError(fission.ErrorNameExists, "key already exists")
|
||||
} else {
|
||||
c.cache[req.key] = &Value{
|
||||
value: req.value,
|
||||
|
||||
+2
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Kubernetes 1.6+ with Beta APIs enabled
|
||||
- Kubernetes 1.8 or later
|
||||
|
||||
|
||||
## Helm charts
|
||||
@@ -47,6 +47,7 @@ The following table lists the configurable parameters of the Fission chart and t
|
||||
| `controllerPort` | Fission Controller Service Port | `31313` |
|
||||
| `routerPort` | Fission Router Service Port | `31314` |
|
||||
| `functionNamespace` | Namespace for Fission functions | `fission-function` |
|
||||
| `builderNamespace` | Namespace for Fission environment builders | `fission-builder` |
|
||||
| `openshift` | RBAC for openshift | `false` |
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
apiVersion: v1
|
||||
name: fission-all
|
||||
version: 0.2.1
|
||||
version: 0.4.0rc
|
||||
description: Fission is a fast serverless framework for Kubernetes.
|
||||
keywords:
|
||||
- fission
|
||||
@@ -12,4 +12,4 @@ maintainers:
|
||||
- name: Ta Ching Chen
|
||||
email: contact@tachingchen.com
|
||||
engine: gotpl
|
||||
appVersion: 0.2.1
|
||||
appVersion: 0.4.0rc
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
1. Install the client CLI.
|
||||
|
||||
Mac:
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/v0.2.1/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0rc/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
|
||||
Linux:
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/v0.2.1/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0rc/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
|
||||
Windows:
|
||||
For Windows, you can use the linux binary on WSL. Or you can download this windows executable: https://github.com/fission/fission/releases/download/v0.2.1/fission-cli-windows.exe
|
||||
For Windows, you can use the linux binary on WSL. Or you can download this windows executable: https://github.com/fission/fission/releases/download/0.4.0rc/fission-cli-windows.exe
|
||||
|
||||
2. Set the FISSION_URL and FISSION_ROUTER environment variables.
|
||||
|
||||
|
||||
@@ -81,6 +81,15 @@ metadata:
|
||||
name: fission-function
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: {{ .Values.builderNamespace }}
|
||||
labels:
|
||||
name: fission-builder
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
@@ -122,7 +131,7 @@ roleRef:
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: fission-tpr
|
||||
name: fission-crd
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: fission-svc
|
||||
@@ -143,7 +152,7 @@ metadata:
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: fission-fetcher-tpr
|
||||
name: fission-fetcher-crd
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: fission-fetcher
|
||||
@@ -153,6 +162,27 @@ roleRef:
|
||||
name: cluster-admin
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: fission-builder
|
||||
namespace: {{ .Values.builderNamespace }}
|
||||
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: fission-builder-crd
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: fission-builder
|
||||
namespace: {{ .Values.builderNamespace }}
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: cluster-admin
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
{{ end }}
|
||||
|
||||
---
|
||||
@@ -240,6 +270,51 @@ spec:
|
||||
value: "{{ .Values.fetcherImage }}:{{ .Values.fetcherImageTag }}"
|
||||
- name: FETCHER_IMAGE_PULL_POLICY
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
- name: RUNTIME_IMAGE_PULL_POLICY
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
serviceAccount: fission-svc
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: buildermgr
|
||||
labels:
|
||||
svc: buildermgr
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8889
|
||||
selector:
|
||||
svc: buildermgr
|
||||
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: buildermgr
|
||||
labels:
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
svc: buildermgr
|
||||
spec:
|
||||
containers:
|
||||
- name: buildermgr
|
||||
image: "{{ .Values.image }}:{{ .Values.imageTag }}"
|
||||
imagePullPolicy: {{ .Values.pullPolicy }}
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--builderMgrPort", "8889", "--storageSvcUrl", "http://storagesvc.{{ .Release.Namespace }}", "--envbuilder-namespace", "{{ .Values.builderNamespace }}"]
|
||||
env:
|
||||
- name: FETCHER_IMAGE
|
||||
value: "{{ .Values.fetcherImage }}:{{ .Values.fetcherImageTag }}"
|
||||
- name: FETCHER_IMAGE_PULL_POLICY
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
serviceAccount: fission-svc
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
{{ if .Values.analytics }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ template "fullname" . }}
|
||||
labels:
|
||||
# The "release" convention makes it easy to tie a release to all of the
|
||||
# Kubernetes resources that were created as part of that release.
|
||||
release: {{ .Release.Name }}
|
||||
# This makes it easy to audit chart usage.
|
||||
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app: {{ template "name" . }}
|
||||
annotations:
|
||||
# This is what defines this resource as a hook. Without this line, the
|
||||
# job is considered part of the release.
|
||||
"helm.sh/hook": post-install
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
name: {{ template "fullname" . }}
|
||||
labels:
|
||||
release: {{ .Release.Name }}
|
||||
app: {{ template "name" . }}
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: post-install-job
|
||||
image: "fission/alpinecurl"
|
||||
command: ["sh", "-c", "/Usr/bin/curl -m 5 -H \"Content-Type: application/json\" -X POST -d '{\"type\": \"helm-post-install\", \"chartName\": \"{{ .Chart.Name }}\", \"chartName\": \"{{ .Chart.Version }}\"}' https://g.fission.sh/analytics || true"]
|
||||
{{ end }}
|
||||
@@ -13,13 +13,13 @@ image: fission/fission-bundle
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
## Fission image version
|
||||
imageTag: v0.2.1
|
||||
imageTag: 0.3.0
|
||||
|
||||
## Fission fetcher repository
|
||||
fetcherImage: fission/fetcher
|
||||
|
||||
## Fission fetcher image version
|
||||
fetcherImageTag: v0.2.1
|
||||
fetcherImageTag: 0.3.0
|
||||
|
||||
## Port at which Fission controller service should be exposed
|
||||
controllerPort: 31313
|
||||
@@ -34,6 +34,10 @@ natsStreamingPort: 31316
|
||||
## the release namespace)
|
||||
functionNamespace: fission-function
|
||||
|
||||
## Namespace in which to run fission builders (this is different from
|
||||
## the release namespace)
|
||||
builderNamespace: fission-builder
|
||||
|
||||
## Set up openshift RBAC rule
|
||||
openshift: false
|
||||
|
||||
@@ -58,3 +62,7 @@ persistence:
|
||||
# storageClass:
|
||||
accessMode: ReadWriteOnce
|
||||
size: 8Gi
|
||||
|
||||
## Analytics let us count how many people installed fission. Set to
|
||||
## false to disable analytics.
|
||||
analytics: true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
apiVersion: v1
|
||||
name: fission-core
|
||||
version: 0.2.1
|
||||
version: 0.4.0rc
|
||||
description: Fission is a fast serverless framework for Kubernetes.
|
||||
keywords:
|
||||
- fission
|
||||
@@ -12,4 +12,4 @@ maintainers:
|
||||
- name: Ta Ching Chen
|
||||
email: contact@tachingchen.com
|
||||
engine: gotpl
|
||||
appVersion: 0.2.1
|
||||
appVersion: 0.4.0rc
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
1. Install the client CLI.
|
||||
|
||||
Mac:
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/v0.2.1/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0rc/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
|
||||
Linux:
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/v0.2.1/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
$ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0rc/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
|
||||
|
||||
Windows:
|
||||
For Windows, you can use the linux binary on WSL. Or you can download this windows executable: https://github.com/fission/fission/releases/download/v0.2.1/fission-cli-windows.exe
|
||||
For Windows, you can use the linux binary on WSL. Or you can download this windows executable: https://github.com/fission/fission/releases/download/0.4.0rc/fission-cli-windows.exe
|
||||
|
||||
2. Set the FISSION_URL and FISSION_ROUTER environment variables.
|
||||
|
||||
|
||||
@@ -81,6 +81,15 @@ metadata:
|
||||
name: fission-function
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: {{ .Values.builderNamespace }}
|
||||
labels:
|
||||
name: fission-builder
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
@@ -122,7 +131,7 @@ roleRef:
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: fission-tpr
|
||||
name: fission-crd
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: fission-svc
|
||||
@@ -143,7 +152,7 @@ metadata:
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: fission-fetcher-tpr
|
||||
name: fission-fetcher-crd
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: fission-fetcher
|
||||
@@ -153,6 +162,27 @@ roleRef:
|
||||
name: cluster-admin
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: fission-builder
|
||||
namespace: {{ .Values.builderNamespace }}
|
||||
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: fission-builder-crd
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: fission-builder
|
||||
namespace: {{ .Values.builderNamespace }}
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: cluster-admin
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
{{ end }}
|
||||
|
||||
---
|
||||
@@ -242,6 +272,49 @@ spec:
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
serviceAccount: fission-svc
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: buildermgr
|
||||
labels:
|
||||
svc: buildermgr
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8889
|
||||
selector:
|
||||
svc: buildermgr
|
||||
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: buildermgr
|
||||
labels:
|
||||
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
svc: buildermgr
|
||||
spec:
|
||||
containers:
|
||||
- name: buildermgr
|
||||
image: "{{ .Values.image }}:{{ .Values.imageTag }}"
|
||||
imagePullPolicy: {{ .Values.pullPolicy }}
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--builderMgrPort", "8889", "--storageSvcUrl", "http://storagesvc.{{ .Release.Namespace }}", "--envbuilder-namespace", "{{ .Values.builderNamespace }}"]
|
||||
env:
|
||||
- name: FETCHER_IMAGE
|
||||
value: "{{ .Values.fetcherImage }}:{{ .Values.fetcherImageTag }}"
|
||||
- name: FETCHER_IMAGE_PULL_POLICY
|
||||
value: "{{ .Values.pullPolicy }}"
|
||||
serviceAccount: fission-svc
|
||||
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
{{ if .Values.analytics }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ template "fullname" . }}
|
||||
labels:
|
||||
# The "release" convention makes it easy to tie a release to all of the
|
||||
# Kubernetes resources that were created as part of that release.
|
||||
release: {{ .Release.Name }}
|
||||
# This makes it easy to audit chart usage.
|
||||
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app: {{ template "name" . }}
|
||||
annotations:
|
||||
# This is what defines this resource as a hook. Without this line, the
|
||||
# job is considered part of the release.
|
||||
"helm.sh/hook": post-install
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
name: {{ template "fullname" . }}
|
||||
labels:
|
||||
release: {{ .Release.Name }}
|
||||
app: {{ template "name" . }}
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: post-install-job
|
||||
image: "fission/alpinecurl"
|
||||
command: ["sh", "-c", "/usr/bin/curl -m 5 -H \"Content-Type: application/json\" -X POST -d '{\"type\": \"helm-post-install\", \"chartName\": \"{{ .Chart.Name }}\", \"chartName\": \"{{ .Chart.Version }}\"}' https://g.fission.sh/analytics || true"]
|
||||
{{ end }}
|
||||
@@ -10,7 +10,7 @@ serviceType: LoadBalancer
|
||||
image: fission/fission-bundle
|
||||
|
||||
## Fission image version
|
||||
imageTag: v0.2.1
|
||||
imageTag: 0.3.0
|
||||
|
||||
## Image pull policy
|
||||
pullPolicy: IfNotPresent
|
||||
@@ -19,7 +19,7 @@ pullPolicy: IfNotPresent
|
||||
fetcherImage: fission/fetcher
|
||||
|
||||
## Fission fetcher image version
|
||||
fetcherImageTag: v0.2.1
|
||||
fetcherImageTag: 0.3.0
|
||||
|
||||
## Port at which Fission controller service should be exposed
|
||||
controllerPort: 31313
|
||||
@@ -31,6 +31,10 @@ routerPort: 31314
|
||||
## the release namespace)
|
||||
functionNamespace: fission-function
|
||||
|
||||
## Namespace in which to run fission builders (this is different from
|
||||
## the release namespace)
|
||||
builderNamespace: fission-builder
|
||||
|
||||
## Set up openshift RBAC rule
|
||||
openshift: false
|
||||
|
||||
@@ -43,3 +47,7 @@ persistence:
|
||||
# storageClass:
|
||||
accessMode: ReadWriteOnce
|
||||
size: 8Gi
|
||||
|
||||
## Analytics let us count how many people installed fission. Set to
|
||||
## false to disable analytics.
|
||||
analytics: true
|
||||
|
||||
+28
-5
@@ -26,17 +26,21 @@ import (
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
log "github.com/sirupsen/logrus"
|
||||
kerrors "k8s.io/client-go/1.5/pkg/api/errors"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/crd"
|
||||
"github.com/fission/fission/fission/logdb"
|
||||
"github.com/fission/fission/tpr"
|
||||
)
|
||||
|
||||
type (
|
||||
API struct {
|
||||
fissionClient *tpr.FissionClient
|
||||
fissionClient *crd.FissionClient
|
||||
kubernetesClient *kubernetes.Clientset
|
||||
storageServiceUrl string
|
||||
builderManagerUrl string
|
||||
workflowApiUrl string
|
||||
}
|
||||
|
||||
logDBConfig struct {
|
||||
@@ -47,7 +51,7 @@ type (
|
||||
)
|
||||
|
||||
func MakeAPI() (*API, error) {
|
||||
api, err := makeTPRBackedAPI()
|
||||
api, err := makeCRDBackedAPI()
|
||||
|
||||
u := os.Getenv("STORAGE_SERVICE_URL")
|
||||
if len(u) > 0 {
|
||||
@@ -56,6 +60,20 @@ func MakeAPI() (*API, error) {
|
||||
api.storageServiceUrl = "http://storagesvc"
|
||||
}
|
||||
|
||||
u = os.Getenv("BUILDER_MANAGER_URL")
|
||||
if len(u) > 0 {
|
||||
api.builderManagerUrl = strings.TrimSuffix(u, "/")
|
||||
} else {
|
||||
api.builderManagerUrl = "http://buildermgr"
|
||||
}
|
||||
|
||||
wfEnv := os.Getenv("WORKFLOW_API_URL")
|
||||
if len(u) > 0 {
|
||||
api.workflowApiUrl = strings.TrimSuffix(wfEnv, "/")
|
||||
} else {
|
||||
api.workflowApiUrl = "http://workflows-apiserver"
|
||||
}
|
||||
|
||||
return api, err
|
||||
}
|
||||
|
||||
@@ -102,7 +120,7 @@ func (api *API) getLogDBConfig(dbType string) logDBConfig {
|
||||
|
||||
func (api *API) HomeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
fmt.Fprintf(w, "{\"message\": \"Fission API\", \"version\": \"0.2.1\"}\n")
|
||||
fmt.Fprintf(w, "{\"message\": \"Fission API\", \"version\": \"0.4.0rc\"}\n")
|
||||
}
|
||||
|
||||
func (api *API) ApiVersionMismatchHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -158,8 +176,13 @@ func (api *API) Serve(port int) {
|
||||
r.HandleFunc("/v2/triggers/messagequeue/{mqTrigger}", api.MessageQueueTriggerApiUpdate).Methods("PUT")
|
||||
r.HandleFunc("/v2/triggers/messagequeue/{mqTrigger}", api.MessageQueueTriggerApiDelete).Methods("DELETE")
|
||||
|
||||
r.HandleFunc("/v2/deleteTpr", api.Tpr2crdApi).Methods("DELETE")
|
||||
|
||||
r.HandleFunc("/proxy/{dbType}", api.FunctionLogsApiPost).Methods("POST")
|
||||
r.HandleFunc("/proxy/storage/v1/archive", api.StorageServiceProxy)
|
||||
r.HandleFunc("/proxy/buildermgr/v1/build", api.BuilderManagerBuildProxy)
|
||||
r.HandleFunc("/proxy/logs/{function}", api.FunctionPodLogs).Methods("POST")
|
||||
r.HandleFunc("/proxy/workflows-apiserver/{path:.*}", api.WorkflowApiserverProxy)
|
||||
|
||||
address := fmt.Sprintf(":%v", port)
|
||||
|
||||
|
||||
+50
-45
@@ -18,6 +18,7 @@ package controller
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -25,11 +26,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/controller/client"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
var g struct {
|
||||
@@ -72,13 +73,10 @@ func assertCronSpecFails(err error) {
|
||||
}
|
||||
|
||||
func TestFunctionApi(t *testing.T) {
|
||||
name1 := "foo"
|
||||
name2 := "bar"
|
||||
|
||||
testFunc := &tpr.Function{
|
||||
Metadata: api.ObjectMeta{
|
||||
Name: name1,
|
||||
Namespace: api.NamespaceDefault,
|
||||
testFunc := &crd.Function{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: fission.FunctionSpec{
|
||||
Environment: fission.EnvironmentReference{
|
||||
@@ -89,30 +87,36 @@ func TestFunctionApi(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err := g.client.FunctionGet(&api.ObjectMeta{
|
||||
_, err := g.client.FunctionGet(&metav1.ObjectMeta{
|
||||
Name: testFunc.Metadata.Name,
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
})
|
||||
assertNotFoundFailure(err, "function")
|
||||
|
||||
_, err = g.client.FunctionCreate(testFunc)
|
||||
m, err := g.client.FunctionCreate(testFunc)
|
||||
panicIf(err)
|
||||
defer func() {
|
||||
err := g.client.FunctionDelete(m)
|
||||
panicIf(err)
|
||||
}()
|
||||
|
||||
_, err = g.client.FunctionCreate(testFunc)
|
||||
assertNameReuseFailure(err, "function")
|
||||
|
||||
testFunc.Metadata.ResourceVersion = m.ResourceVersion
|
||||
testFunc.Spec.Package.FunctionName = "yyy"
|
||||
_, err = g.client.FunctionUpdate(testFunc)
|
||||
panicIf(err)
|
||||
|
||||
testFunc.Metadata.Name = name2
|
||||
_, err = g.client.FunctionCreate(testFunc)
|
||||
testFunc.Metadata.ResourceVersion = ""
|
||||
testFunc.Metadata.Name = "bar"
|
||||
m2, err := g.client.FunctionCreate(testFunc)
|
||||
panicIf(err)
|
||||
defer g.client.FunctionDelete(m2)
|
||||
|
||||
funcs, err := g.client.FunctionList()
|
||||
panicIf(err)
|
||||
assert(len(funcs) == 2,
|
||||
"created two functions, but didn't find them")
|
||||
assert(len(funcs) == 2, fmt.Sprintf("created two functions, but found %v", len(funcs)))
|
||||
|
||||
funcs_url := g.client.Url + "/v2/functions"
|
||||
resp, err := http.Get(funcs_url)
|
||||
@@ -127,18 +131,13 @@ func TestFunctionApi(t *testing.T) {
|
||||
}
|
||||
}
|
||||
assert(found, "incorrect response content type")
|
||||
|
||||
err = g.client.FunctionDelete(&api.ObjectMeta{Name: name1, Namespace: api.NamespaceDefault})
|
||||
panicIf(err)
|
||||
err = g.client.FunctionDelete(&api.ObjectMeta{Name: name2, Namespace: api.NamespaceDefault})
|
||||
panicIf(err)
|
||||
}
|
||||
|
||||
func TestHTTPTriggerApi(t *testing.T) {
|
||||
testTrigger := &tpr.Httptrigger{
|
||||
Metadata: api.ObjectMeta{
|
||||
testTrigger := &crd.HTTPTrigger{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: fission.HTTPTriggerSpec{
|
||||
RelativeURL: "/hello",
|
||||
@@ -148,9 +147,9 @@ func TestHTTPTriggerApi(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err := g.client.HTTPTriggerGet(&api.ObjectMeta{
|
||||
_, err := g.client.HTTPTriggerGet(&metav1.ObjectMeta{
|
||||
Name: testTrigger.Metadata.Name,
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
})
|
||||
assertNotFoundFailure(err, "httptrigger")
|
||||
|
||||
@@ -165,10 +164,12 @@ func TestHTTPTriggerApi(t *testing.T) {
|
||||
panicIf(err)
|
||||
assert(testTrigger.Spec == tr.Spec, "trigger should match after reading")
|
||||
|
||||
testTrigger.Metadata.ResourceVersion = m.ResourceVersion
|
||||
testTrigger.Spec.RelativeURL = "/hi"
|
||||
_, err = g.client.HTTPTriggerUpdate(testTrigger)
|
||||
panicIf(err)
|
||||
|
||||
testTrigger.Metadata.ResourceVersion = ""
|
||||
testTrigger.Metadata.Name = "yyy"
|
||||
_, err = g.client.HTTPTriggerCreate(testTrigger)
|
||||
assert(err != nil, "duplicate trigger should not be allowed")
|
||||
@@ -180,14 +181,14 @@ func TestHTTPTriggerApi(t *testing.T) {
|
||||
|
||||
ts, err := g.client.HTTPTriggerList()
|
||||
panicIf(err)
|
||||
assert(len(ts) == 2, "created two triggers, but didn't find them")
|
||||
assert(len(ts) == 2, fmt.Sprintf("created two triggers, but found %v", len(ts)))
|
||||
}
|
||||
|
||||
func TestEnvironmentApi(t *testing.T) {
|
||||
testEnv := &tpr.Environment{
|
||||
Metadata: api.ObjectMeta{
|
||||
testEnv := &crd.Environment{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: fission.EnvironmentSpec{
|
||||
Runtime: fission.Runtime{
|
||||
@@ -195,9 +196,9 @@ func TestEnvironmentApi(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err := g.client.EnvironmentGet(&api.ObjectMeta{
|
||||
_, err := g.client.EnvironmentGet(&metav1.ObjectMeta{
|
||||
Name: testEnv.Metadata.Name,
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
})
|
||||
assertNotFoundFailure(err, "environment")
|
||||
|
||||
@@ -212,10 +213,12 @@ func TestEnvironmentApi(t *testing.T) {
|
||||
panicIf(err)
|
||||
assert(testEnv.Spec == e.Spec, "env should match after reading")
|
||||
|
||||
testEnv.Metadata.ResourceVersion = m.ResourceVersion
|
||||
testEnv.Spec.Runtime.Image = "another-img"
|
||||
_, err = g.client.EnvironmentUpdate(testEnv)
|
||||
panicIf(err)
|
||||
|
||||
testEnv.Metadata.ResourceVersion = ""
|
||||
testEnv.Metadata.Name = "bar"
|
||||
m2, err := g.client.EnvironmentCreate(testEnv)
|
||||
panicIf(err)
|
||||
@@ -223,14 +226,14 @@ func TestEnvironmentApi(t *testing.T) {
|
||||
|
||||
ts, err := g.client.EnvironmentList()
|
||||
panicIf(err)
|
||||
assert(len(ts) == 2, "created two envs, but didn't find them")
|
||||
assert(len(ts) == 2, fmt.Sprintf("created two envs, but found %v", len(ts)))
|
||||
}
|
||||
|
||||
func TestWatchApi(t *testing.T) {
|
||||
testWatch := &tpr.Kuberneteswatchtrigger{
|
||||
Metadata: api.ObjectMeta{
|
||||
testWatch := &crd.KubernetesWatchTrigger{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "xxx",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: fission.KubernetesWatchTriggerSpec{
|
||||
Namespace: "default",
|
||||
@@ -241,9 +244,9 @@ func TestWatchApi(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err := g.client.WatchGet(&api.ObjectMeta{
|
||||
_, err := g.client.WatchGet(&metav1.ObjectMeta{
|
||||
Name: testWatch.Metadata.Name,
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
})
|
||||
assertNotFoundFailure(err, "watch")
|
||||
|
||||
@@ -267,14 +270,14 @@ func TestWatchApi(t *testing.T) {
|
||||
|
||||
ws, err := g.client.WatchList()
|
||||
panicIf(err)
|
||||
assert(len(ws) == 2, "created two envs, but didn't find them")
|
||||
assert(len(ws) == 2, fmt.Sprintf("created two watches, but found %v", len(ws)))
|
||||
}
|
||||
|
||||
func TestTimeTriggerApi(t *testing.T) {
|
||||
testTrigger := &tpr.Timetrigger{
|
||||
Metadata: api.ObjectMeta{
|
||||
testTrigger := &crd.TimeTrigger{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "xxx",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: fission.TimeTriggerSpec{
|
||||
Cron: "0 30 * * * *",
|
||||
@@ -284,7 +287,7 @@ func TestTimeTriggerApi(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err := g.client.TimeTriggerGet(&api.ObjectMeta{Name: testTrigger.Metadata.Name})
|
||||
_, err := g.client.TimeTriggerGet(&metav1.ObjectMeta{Name: testTrigger.Metadata.Name})
|
||||
assertNotFoundFailure(err, "trigger")
|
||||
|
||||
m, err := g.client.TimeTriggerCreate(testTrigger)
|
||||
@@ -298,10 +301,12 @@ func TestTimeTriggerApi(t *testing.T) {
|
||||
panicIf(err)
|
||||
assert(testTrigger.Spec == tr.Spec, "trigger should match after reading")
|
||||
|
||||
testTrigger.Metadata.ResourceVersion = m.ResourceVersion
|
||||
testTrigger.Spec.Cron = "@hourly"
|
||||
_, err = g.client.TimeTriggerUpdate(testTrigger)
|
||||
panicIf(err)
|
||||
|
||||
testTrigger.Metadata.ResourceVersion = ""
|
||||
testTrigger.Metadata.Name = "yyy"
|
||||
testTrigger.Spec.Cron = "Not valid cron spec"
|
||||
_, err = g.client.TimeTriggerCreate(testTrigger)
|
||||
@@ -309,7 +314,7 @@ func TestTimeTriggerApi(t *testing.T) {
|
||||
|
||||
ts, err := g.client.TimeTriggerList()
|
||||
panicIf(err)
|
||||
assert(len(ts) == 1, "created one trigger, but didn't find it")
|
||||
assert(len(ts) == 1, fmt.Sprintf("created two time triggers, but found %v", len(ts)))
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
@@ -324,7 +329,7 @@ func TestMain(m *testing.M) {
|
||||
|
||||
go Start(8888)
|
||||
|
||||
time.Sleep(time.Second)
|
||||
time.Sleep(5 * time.Second)
|
||||
g.client = client.MakeClient("http://localhost:8888")
|
||||
|
||||
resp, err := http.Get("http://localhost:8888/")
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2017 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func (api *API) BuilderManagerBuildProxy(w http.ResponseWriter, r *http.Request) {
|
||||
u := api.builderManagerUrl + "/v1/build"
|
||||
proxy, err := api.getBuilderManagerProxy(u)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("Failed to establish proxy server: %v", err)
|
||||
log.Println(msg)
|
||||
http.Error(w, msg, 500)
|
||||
return
|
||||
}
|
||||
proxy.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (api *API) getBuilderManagerProxy(targetUrl string) (*httputil.ReverseProxy, error) {
|
||||
svcUrl, err := url.Parse(targetUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// set up proxy server director
|
||||
director := func(req *http.Request) {
|
||||
// only replace url Scheme and Host to remote server
|
||||
// and leave query string intact
|
||||
req.URL.Scheme = svcUrl.Scheme
|
||||
req.URL.Host = svcUrl.Host
|
||||
req.URL.Path = svcUrl.Path
|
||||
}
|
||||
return &httputil.ReverseProxy{
|
||||
Director: director,
|
||||
}, nil
|
||||
}
|
||||
@@ -22,12 +22,12 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (c *Client) EnvironmentCreate(env *tpr.Environment) (*api.ObjectMeta, error) {
|
||||
func (c *Client) EnvironmentCreate(env *crd.Environment) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(env)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -44,7 +44,7 @@ func (c *Client) EnvironmentCreate(env *tpr.Environment) (*api.ObjectMeta, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -53,7 +53,7 @@ func (c *Client) EnvironmentCreate(env *tpr.Environment) (*api.ObjectMeta, error
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) EnvironmentGet(m *api.ObjectMeta) (*tpr.Environment, error) {
|
||||
func (c *Client) EnvironmentGet(m *metav1.ObjectMeta) (*crd.Environment, error) {
|
||||
relativeUrl := fmt.Sprintf("environments/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
|
||||
@@ -68,7 +68,7 @@ func (c *Client) EnvironmentGet(m *api.ObjectMeta) (*tpr.Environment, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var env tpr.Environment
|
||||
var env crd.Environment
|
||||
err = json.Unmarshal(body, &env)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -77,7 +77,7 @@ func (c *Client) EnvironmentGet(m *api.ObjectMeta) (*tpr.Environment, error) {
|
||||
return &env, nil
|
||||
}
|
||||
|
||||
func (c *Client) EnvironmentUpdate(env *tpr.Environment) (*api.ObjectMeta, error) {
|
||||
func (c *Client) EnvironmentUpdate(env *crd.Environment) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(env)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -95,7 +95,7 @@ func (c *Client) EnvironmentUpdate(env *tpr.Environment) (*api.ObjectMeta, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -103,14 +103,14 @@ func (c *Client) EnvironmentUpdate(env *tpr.Environment) (*api.ObjectMeta, error
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) EnvironmentDelete(m *api.ObjectMeta) error {
|
||||
func (c *Client) EnvironmentDelete(m *metav1.ObjectMeta) error {
|
||||
relativeUrl := fmt.Sprintf("environments/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
|
||||
return c.delete(relativeUrl)
|
||||
}
|
||||
|
||||
func (c *Client) EnvironmentList() ([]tpr.Environment, error) {
|
||||
func (c *Client) EnvironmentList() ([]crd.Environment, error) {
|
||||
resp, err := http.Get(c.url("environments"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -122,7 +122,7 @@ func (c *Client) EnvironmentList() ([]tpr.Environment, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
envs := make([]tpr.Environment, 0)
|
||||
envs := make([]crd.Environment, 0)
|
||||
err = json.Unmarshal(body, &envs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -22,12 +22,12 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (c *Client) FunctionCreate(f *tpr.Function) (*api.ObjectMeta, error) {
|
||||
func (c *Client) FunctionCreate(f *crd.Function) (*metav1.ObjectMeta, error) {
|
||||
|
||||
reqbody, err := json.Marshal(f)
|
||||
if err != nil {
|
||||
@@ -45,7 +45,7 @@ func (c *Client) FunctionCreate(f *tpr.Function) (*api.ObjectMeta, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -54,7 +54,7 @@ func (c *Client) FunctionCreate(f *tpr.Function) (*api.ObjectMeta, error) {
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) FunctionGet(m *api.ObjectMeta) (*tpr.Function, error) {
|
||||
func (c *Client) FunctionGet(m *metav1.ObjectMeta) (*crd.Function, error) {
|
||||
relativeUrl := fmt.Sprintf("functions/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
|
||||
@@ -69,7 +69,7 @@ func (c *Client) FunctionGet(m *api.ObjectMeta) (*tpr.Function, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var f tpr.Function
|
||||
var f crd.Function
|
||||
err = json.Unmarshal(body, &f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -78,7 +78,7 @@ func (c *Client) FunctionGet(m *api.ObjectMeta) (*tpr.Function, error) {
|
||||
return &f, nil
|
||||
}
|
||||
|
||||
func (c *Client) FunctionGetRawDeployment(m *api.ObjectMeta) ([]byte, error) {
|
||||
func (c *Client) FunctionGetRawDeployment(m *metav1.ObjectMeta) ([]byte, error) {
|
||||
relativeUrl := fmt.Sprintf("functions/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
relativeUrl += fmt.Sprintf("&deploymentraw=1")
|
||||
@@ -92,7 +92,7 @@ func (c *Client) FunctionGetRawDeployment(m *api.ObjectMeta) ([]byte, error) {
|
||||
return c.handleResponse(resp)
|
||||
}
|
||||
|
||||
func (c *Client) FunctionUpdate(f *tpr.Function) (*api.ObjectMeta, error) {
|
||||
func (c *Client) FunctionUpdate(f *crd.Function) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -110,7 +110,7 @@ func (c *Client) FunctionUpdate(f *tpr.Function) (*api.ObjectMeta, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -118,13 +118,13 @@ func (c *Client) FunctionUpdate(f *tpr.Function) (*api.ObjectMeta, error) {
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) FunctionDelete(m *api.ObjectMeta) error {
|
||||
func (c *Client) FunctionDelete(m *metav1.ObjectMeta) error {
|
||||
relativeUrl := fmt.Sprintf("functions/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
return c.delete(relativeUrl)
|
||||
}
|
||||
|
||||
func (c *Client) FunctionList() ([]tpr.Function, error) {
|
||||
func (c *Client) FunctionList() ([]crd.Function, error) {
|
||||
resp, err := http.Get(c.url("functions"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -136,7 +136,7 @@ func (c *Client) FunctionList() ([]tpr.Function, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
funcs := make([]tpr.Function, 0)
|
||||
funcs := make([]crd.Function, 0)
|
||||
err = json.Unmarshal(body, &funcs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -22,12 +22,12 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (c *Client) HTTPTriggerCreate(t *tpr.Httptrigger) (*api.ObjectMeta, error) {
|
||||
func (c *Client) HTTPTriggerCreate(t *crd.HTTPTrigger) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -44,7 +44,7 @@ func (c *Client) HTTPTriggerCreate(t *tpr.Httptrigger) (*api.ObjectMeta, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -53,7 +53,7 @@ func (c *Client) HTTPTriggerCreate(t *tpr.Httptrigger) (*api.ObjectMeta, error)
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) HTTPTriggerGet(m *api.ObjectMeta) (*tpr.Httptrigger, error) {
|
||||
func (c *Client) HTTPTriggerGet(m *metav1.ObjectMeta) (*crd.HTTPTrigger, error) {
|
||||
relativeUrl := fmt.Sprintf("triggers/http/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
|
||||
@@ -68,7 +68,7 @@ func (c *Client) HTTPTriggerGet(m *api.ObjectMeta) (*tpr.Httptrigger, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var t tpr.Httptrigger
|
||||
var t crd.HTTPTrigger
|
||||
err = json.Unmarshal(body, &t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -77,7 +77,7 @@ func (c *Client) HTTPTriggerGet(m *api.ObjectMeta) (*tpr.Httptrigger, error) {
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
func (c *Client) HTTPTriggerUpdate(t *tpr.Httptrigger) (*api.ObjectMeta, error) {
|
||||
func (c *Client) HTTPTriggerUpdate(t *crd.HTTPTrigger) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -95,7 +95,7 @@ func (c *Client) HTTPTriggerUpdate(t *tpr.Httptrigger) (*api.ObjectMeta, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -103,13 +103,13 @@ func (c *Client) HTTPTriggerUpdate(t *tpr.Httptrigger) (*api.ObjectMeta, error)
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) HTTPTriggerDelete(m *api.ObjectMeta) error {
|
||||
func (c *Client) HTTPTriggerDelete(m *metav1.ObjectMeta) error {
|
||||
relativeUrl := fmt.Sprintf("triggers/http/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
return c.delete(relativeUrl)
|
||||
}
|
||||
|
||||
func (c *Client) HTTPTriggerList() ([]tpr.Httptrigger, error) {
|
||||
func (c *Client) HTTPTriggerList() ([]crd.HTTPTrigger, error) {
|
||||
resp, err := http.Get(c.url("triggers/http"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -121,7 +121,7 @@ func (c *Client) HTTPTriggerList() ([]tpr.Httptrigger, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
triggers := make([]tpr.Httptrigger, 0)
|
||||
triggers := make([]crd.HTTPTrigger, 0)
|
||||
err = json.Unmarshal(body, &triggers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -22,13 +22,13 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (c *Client) WatchCreate(w *tpr.Kuberneteswatchtrigger) (*api.ObjectMeta, error) {
|
||||
func (c *Client) WatchCreate(w *crd.KubernetesWatchTrigger) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(w)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -45,7 +45,7 @@ func (c *Client) WatchCreate(w *tpr.Kuberneteswatchtrigger) (*api.ObjectMeta, er
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -54,7 +54,7 @@ func (c *Client) WatchCreate(w *tpr.Kuberneteswatchtrigger) (*api.ObjectMeta, er
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) WatchGet(m *api.ObjectMeta) (*tpr.Kuberneteswatchtrigger, error) {
|
||||
func (c *Client) WatchGet(m *metav1.ObjectMeta) (*crd.KubernetesWatchTrigger, error) {
|
||||
relativeUrl := fmt.Sprintf("watches/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
|
||||
@@ -69,7 +69,7 @@ func (c *Client) WatchGet(m *api.ObjectMeta) (*tpr.Kuberneteswatchtrigger, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var w tpr.Kuberneteswatchtrigger
|
||||
var w crd.KubernetesWatchTrigger
|
||||
err = json.Unmarshal(body, &w)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -78,18 +78,18 @@ func (c *Client) WatchGet(m *api.ObjectMeta) (*tpr.Kuberneteswatchtrigger, error
|
||||
return &w, nil
|
||||
}
|
||||
|
||||
func (c *Client) WatchUpdate(w *tpr.Kuberneteswatchtrigger) (*api.ObjectMeta, error) {
|
||||
func (c *Client) WatchUpdate(w *crd.KubernetesWatchTrigger) (*metav1.ObjectMeta, error) {
|
||||
return nil, fission.MakeError(fission.ErrorNotImplmented,
|
||||
"watch update not implemented")
|
||||
}
|
||||
|
||||
func (c *Client) WatchDelete(m *api.ObjectMeta) error {
|
||||
func (c *Client) WatchDelete(m *metav1.ObjectMeta) error {
|
||||
relativeUrl := fmt.Sprintf("watches/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
return c.delete(relativeUrl)
|
||||
}
|
||||
|
||||
func (c *Client) WatchList() ([]tpr.Kuberneteswatchtrigger, error) {
|
||||
func (c *Client) WatchList() ([]crd.KubernetesWatchTrigger, error) {
|
||||
resp, err := http.Get(c.url("watches"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -101,7 +101,7 @@ func (c *Client) WatchList() ([]tpr.Kuberneteswatchtrigger, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
watches := make([]tpr.Kuberneteswatchtrigger, 0)
|
||||
watches := make([]crd.KubernetesWatchTrigger, 0)
|
||||
err = json.Unmarshal(body, &watches)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -22,12 +22,12 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (c *Client) MessageQueueTriggerCreate(t *tpr.Messagequeuetrigger) (*api.ObjectMeta, error) {
|
||||
func (c *Client) MessageQueueTriggerCreate(t *crd.MessageQueueTrigger) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -44,7 +44,7 @@ func (c *Client) MessageQueueTriggerCreate(t *tpr.Messagequeuetrigger) (*api.Obj
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -53,7 +53,7 @@ func (c *Client) MessageQueueTriggerCreate(t *tpr.Messagequeuetrigger) (*api.Obj
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) MessageQueueTriggerGet(m *api.ObjectMeta) (*tpr.Messagequeuetrigger, error) {
|
||||
func (c *Client) MessageQueueTriggerGet(m *metav1.ObjectMeta) (*crd.MessageQueueTrigger, error) {
|
||||
relativeUrl := fmt.Sprintf("triggers/messagequeue/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
|
||||
@@ -68,7 +68,7 @@ func (c *Client) MessageQueueTriggerGet(m *api.ObjectMeta) (*tpr.Messagequeuetri
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var t tpr.Messagequeuetrigger
|
||||
var t crd.MessageQueueTrigger
|
||||
err = json.Unmarshal(body, &t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -77,7 +77,7 @@ func (c *Client) MessageQueueTriggerGet(m *api.ObjectMeta) (*tpr.Messagequeuetri
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
func (c *Client) MessageQueueTriggerUpdate(mqTrigger *tpr.Messagequeuetrigger) (*api.ObjectMeta, error) {
|
||||
func (c *Client) MessageQueueTriggerUpdate(mqTrigger *crd.MessageQueueTrigger) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(mqTrigger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -95,7 +95,7 @@ func (c *Client) MessageQueueTriggerUpdate(mqTrigger *tpr.Messagequeuetrigger) (
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -103,13 +103,13 @@ func (c *Client) MessageQueueTriggerUpdate(mqTrigger *tpr.Messagequeuetrigger) (
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) MessageQueueTriggerDelete(m *api.ObjectMeta) error {
|
||||
func (c *Client) MessageQueueTriggerDelete(m *metav1.ObjectMeta) error {
|
||||
relativeUrl := fmt.Sprintf("triggers/messagequeue/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
return c.delete(relativeUrl)
|
||||
}
|
||||
|
||||
func (c *Client) MessageQueueTriggerList(mqType string) ([]tpr.Messagequeuetrigger, error) {
|
||||
func (c *Client) MessageQueueTriggerList(mqType string) ([]crd.MessageQueueTrigger, error) {
|
||||
relativeUrl := "triggers/messagequeue"
|
||||
if len(mqType) > 0 {
|
||||
// TODO remove this, replace with field selector
|
||||
@@ -127,7 +127,7 @@ func (c *Client) MessageQueueTriggerList(mqType string) ([]tpr.Messagequeuetrigg
|
||||
return nil, err
|
||||
}
|
||||
|
||||
triggers := make([]tpr.Messagequeuetrigger, 0)
|
||||
triggers := make([]crd.MessageQueueTrigger, 0)
|
||||
err = json.Unmarshal(body, &triggers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -22,12 +22,12 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (c *Client) PackageCreate(f *tpr.Package) (*api.ObjectMeta, error) {
|
||||
func (c *Client) PackageCreate(f *crd.Package) (*metav1.ObjectMeta, error) {
|
||||
|
||||
reqbody, err := json.Marshal(f)
|
||||
if err != nil {
|
||||
@@ -45,7 +45,7 @@ func (c *Client) PackageCreate(f *tpr.Package) (*api.ObjectMeta, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -54,7 +54,7 @@ func (c *Client) PackageCreate(f *tpr.Package) (*api.ObjectMeta, error) {
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) PackageGet(m *api.ObjectMeta) (*tpr.Package, error) {
|
||||
func (c *Client) PackageGet(m *metav1.ObjectMeta) (*crd.Package, error) {
|
||||
relativeUrl := fmt.Sprintf("packages/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
|
||||
@@ -69,7 +69,7 @@ func (c *Client) PackageGet(m *api.ObjectMeta) (*tpr.Package, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var f tpr.Package
|
||||
var f crd.Package
|
||||
err = json.Unmarshal(body, &f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -78,7 +78,7 @@ func (c *Client) PackageGet(m *api.ObjectMeta) (*tpr.Package, error) {
|
||||
return &f, nil
|
||||
}
|
||||
|
||||
func (c *Client) PackageUpdate(f *tpr.Package) (*api.ObjectMeta, error) {
|
||||
func (c *Client) PackageUpdate(f *crd.Package) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -96,7 +96,7 @@ func (c *Client) PackageUpdate(f *tpr.Package) (*api.ObjectMeta, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -104,13 +104,13 @@ func (c *Client) PackageUpdate(f *tpr.Package) (*api.ObjectMeta, error) {
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) PackageDelete(m *api.ObjectMeta) error {
|
||||
func (c *Client) PackageDelete(m *metav1.ObjectMeta) error {
|
||||
relativeUrl := fmt.Sprintf("packages/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
return c.delete(relativeUrl)
|
||||
}
|
||||
|
||||
func (c *Client) PackageList() ([]tpr.Package, error) {
|
||||
func (c *Client) PackageList() ([]crd.Package, error) {
|
||||
resp, err := http.Get(c.url("packages"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -122,7 +122,7 @@ func (c *Client) PackageList() ([]tpr.Package, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
funcs := make([]tpr.Package, 0)
|
||||
funcs := make([]crd.Package, 0)
|
||||
err = json.Unmarshal(body, &funcs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -22,12 +22,12 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (c *Client) TimeTriggerCreate(t *tpr.Timetrigger) (*api.ObjectMeta, error) {
|
||||
func (c *Client) TimeTriggerCreate(t *crd.TimeTrigger) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -44,7 +44,7 @@ func (c *Client) TimeTriggerCreate(t *tpr.Timetrigger) (*api.ObjectMeta, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -53,7 +53,7 @@ func (c *Client) TimeTriggerCreate(t *tpr.Timetrigger) (*api.ObjectMeta, error)
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) TimeTriggerGet(m *api.ObjectMeta) (*tpr.Timetrigger, error) {
|
||||
func (c *Client) TimeTriggerGet(m *metav1.ObjectMeta) (*crd.TimeTrigger, error) {
|
||||
relativeUrl := fmt.Sprintf("triggers/time/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
|
||||
@@ -68,7 +68,7 @@ func (c *Client) TimeTriggerGet(m *api.ObjectMeta) (*tpr.Timetrigger, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var t tpr.Timetrigger
|
||||
var t crd.TimeTrigger
|
||||
err = json.Unmarshal(body, &t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -77,7 +77,7 @@ func (c *Client) TimeTriggerGet(m *api.ObjectMeta) (*tpr.Timetrigger, error) {
|
||||
return &t, nil
|
||||
}
|
||||
|
||||
func (c *Client) TimeTriggerUpdate(t *tpr.Timetrigger) (*api.ObjectMeta, error) {
|
||||
func (c *Client) TimeTriggerUpdate(t *crd.TimeTrigger) (*metav1.ObjectMeta, error) {
|
||||
reqbody, err := json.Marshal(t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -95,7 +95,7 @@ func (c *Client) TimeTriggerUpdate(t *tpr.Timetrigger) (*api.ObjectMeta, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var m api.ObjectMeta
|
||||
var m metav1.ObjectMeta
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -103,13 +103,13 @@ func (c *Client) TimeTriggerUpdate(t *tpr.Timetrigger) (*api.ObjectMeta, error)
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
func (c *Client) TimeTriggerDelete(m *api.ObjectMeta) error {
|
||||
func (c *Client) TimeTriggerDelete(m *metav1.ObjectMeta) error {
|
||||
relativeUrl := fmt.Sprintf("triggers/time/%v", m.Name)
|
||||
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
|
||||
return c.delete(relativeUrl)
|
||||
}
|
||||
|
||||
func (c *Client) TimeTriggerList() ([]tpr.Timetrigger, error) {
|
||||
func (c *Client) TimeTriggerList() ([]crd.TimeTrigger, error) {
|
||||
resp, err := http.Get(c.url("triggers/time"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -121,7 +121,7 @@ func (c *Client) TimeTriggerList() ([]tpr.Timetrigger, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
triggers := make([]tpr.Timetrigger, 0)
|
||||
triggers := make([]crd.TimeTrigger, 0)
|
||||
err = json.Unmarshal(body, &triggers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -19,21 +19,21 @@ package controller
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func Start(port int) {
|
||||
fc, kc, err := tpr.MakeFissionClient()
|
||||
fc, _, apiExtClient, err := crd.MakeFissionClient()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to connect to K8s API: %v", err)
|
||||
}
|
||||
|
||||
err = tpr.EnsureFissionTPRs(kc)
|
||||
err = crd.EnsureFissionCRDs(apiExtClient)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create fission TPRs: %v", err)
|
||||
log.Fatalf("Failed to create fission CRDs: %v", err)
|
||||
}
|
||||
|
||||
fc.WaitForTPRs()
|
||||
fc.WaitForCRDs()
|
||||
|
||||
api, err := MakeAPI()
|
||||
if err != nil {
|
||||
|
||||
@@ -20,15 +20,15 @@ import (
|
||||
"errors"
|
||||
"regexp"
|
||||
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func makeTPRBackedAPI() (*API, error) {
|
||||
fissionClient, _, err := tpr.MakeFissionClient()
|
||||
func makeCRDBackedAPI() (*API, error) {
|
||||
fissionClient, kubernetesClient, _, err := crd.MakeFissionClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &API{fissionClient: fissionClient}, nil
|
||||
return &API{fissionClient: fissionClient, kubernetesClient: kubernetesClient}, nil
|
||||
}
|
||||
|
||||
func validateResourceName(name string) error {
|
||||
@@ -23,14 +23,14 @@ import (
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (a *API) EnvironmentApiList(w http.ResponseWriter, r *http.Request) {
|
||||
envs, err := a.fissionClient.Environments(api.NamespaceAll).List(api.ListOptions{})
|
||||
envs, err := a.fissionClient.Environments(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -52,7 +52,7 @@ func (a *API) EnvironmentApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var env tpr.Environment
|
||||
var env crd.Environment
|
||||
err = json.Unmarshal(body, &env)
|
||||
if err != nil {
|
||||
log.Printf("Failed to unmarshal request body: [%v]", body)
|
||||
@@ -87,7 +87,7 @@ func (a *API) EnvironmentApiGet(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["environment"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
env, err := a.fissionClient.Environments(ns).Get(name)
|
||||
@@ -115,7 +115,7 @@ func (a *API) EnvironmentApiUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var env tpr.Environment
|
||||
var env crd.Environment
|
||||
err = json.Unmarshal(body, &env)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -139,6 +139,7 @@ func (a *API) EnvironmentApiUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
a.respondWithSuccess(w, resp)
|
||||
}
|
||||
|
||||
@@ -147,10 +148,10 @@ func (a *API) EnvironmentApiDelete(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["environment"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
err := a.fissionClient.Environments(ns).Delete(name, &api.DeleteOptions{})
|
||||
err := a.fissionClient.Environments(ns).Delete(name, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
|
||||
@@ -18,21 +18,27 @@ package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"sort"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/pkg/api"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (a *API) FunctionApiList(w http.ResponseWriter, r *http.Request) {
|
||||
funcs, err := a.fissionClient.Functions(api.NamespaceAll).List(api.ListOptions{})
|
||||
funcs, err := a.fissionClient.Functions(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -54,7 +60,7 @@ func (a *API) FunctionApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var f tpr.Function
|
||||
var f crd.Function
|
||||
err = json.Unmarshal(body, &f)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -88,7 +94,7 @@ func (a *API) FunctionApiGet(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["function"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
f, err := a.fissionClient.Functions(ns).Get(name)
|
||||
@@ -115,7 +121,7 @@ func (a *API) FunctionApiUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var f tpr.Function
|
||||
var f crd.Function
|
||||
err = json.Unmarshal(body, &f)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -147,10 +153,10 @@ func (a *API) FunctionApiDelete(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["function"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
err := a.fissionClient.Functions(ns).Delete(name, &api.DeleteOptions{})
|
||||
err := a.fissionClient.Functions(ns).Delete(name, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -188,3 +194,65 @@ func (a *API) FunctionLogsApiPost(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
proxy.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// FunctionPodLogs : Get logs for a function directly from pod
|
||||
func (a *API) FunctionPodLogs(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
fnName := vars["function"]
|
||||
ns := vars["namespace"]
|
||||
|
||||
if len(ns) == 0 {
|
||||
ns = "fission-function"
|
||||
}
|
||||
|
||||
f, err := a.fissionClient.Functions(api.NamespaceDefault).Get(fnName)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
envName := f.Spec.Environment.Name
|
||||
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get function Pods first
|
||||
selector := "functionName=" + fnName
|
||||
podList, err := a.kubernetesClient.Core().Pods(ns).List(metav1.ListOptions{LabelSelector: selector})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get the logs for last Pod executed
|
||||
pods := podList.Items
|
||||
sort.Slice(pods, func(i, j int) bool {
|
||||
itime := pods[i].ObjectMeta.CreationTimestamp.Time
|
||||
jtime := pods[j].ObjectMeta.CreationTimestamp.Time
|
||||
return itime.After(jtime)
|
||||
})
|
||||
|
||||
podLogOpts := v1.PodLogOptions{Container: envName} // Only the env container, not fetcher
|
||||
var podLogsReq *restclient.Request
|
||||
if len(pods) > 0 {
|
||||
podLogsReq = a.kubernetesClient.Core().Pods(ns).GetLogs(pods[0].ObjectMeta.Name, &podLogOpts)
|
||||
} else {
|
||||
a.respondWithError(w, errors.New("No active pods found"))
|
||||
return
|
||||
}
|
||||
|
||||
podLogs, err := podLogsReq.Stream()
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
defer podLogs.Close()
|
||||
|
||||
_, err = io.Copy(w, podLogs)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (a *API) HTTPTriggerApiList(w http.ResponseWriter, r *http.Request) {
|
||||
triggers, err := a.fissionClient.Httptriggers(api.NamespaceAll).List(api.ListOptions{})
|
||||
triggers, err := a.fissionClient.HTTPTriggers(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -45,8 +45,8 @@ func (a *API) HTTPTriggerApiList(w http.ResponseWriter, r *http.Request) {
|
||||
a.respondWithSuccess(w, resp)
|
||||
}
|
||||
|
||||
func (a *API) checkHttpTriggerDuplicates(t *tpr.Httptrigger) error {
|
||||
triggers, err := a.fissionClient.Httptriggers(api.NamespaceAll).List(api.ListOptions{})
|
||||
func (a *API) checkHTTPTriggerDuplicates(t *crd.HTTPTrigger) error {
|
||||
triggers, err := a.fissionClient.HTTPTriggers(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -67,7 +67,7 @@ func (a *API) HTTPTriggerApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var t tpr.Httptrigger
|
||||
var t crd.HTTPTrigger
|
||||
err = json.Unmarshal(body, &t)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -81,13 +81,13 @@ func (a *API) HTTPTriggerApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Ensure we don't have a duplicate HTTP route defined (same URL and method)
|
||||
err = a.checkHttpTriggerDuplicates(&t)
|
||||
err = a.checkHTTPTriggerDuplicates(&t)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
tnew, err := a.fissionClient.Httptriggers(t.Metadata.Namespace).Create(&t)
|
||||
tnew, err := a.fissionClient.HTTPTriggers(t.Metadata.Namespace).Create(&t)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -108,10 +108,10 @@ func (a *API) HTTPTriggerApiGet(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["httpTrigger"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
t, err := a.fissionClient.Httptriggers(ns).Get(name)
|
||||
t, err := a.fissionClient.HTTPTriggers(ns).Get(name)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -136,7 +136,7 @@ func (a *API) HTTPTriggerApiUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var t tpr.Httptrigger
|
||||
var t crd.HTTPTrigger
|
||||
err = json.Unmarshal(body, &t)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -149,13 +149,13 @@ func (a *API) HTTPTriggerApiUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.checkHttpTriggerDuplicates(&t)
|
||||
err = a.checkHTTPTriggerDuplicates(&t)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
tnew, err := a.fissionClient.Httptriggers(t.Metadata.Namespace).Update(&t)
|
||||
tnew, err := a.fissionClient.HTTPTriggers(t.Metadata.Namespace).Update(&t)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -174,10 +174,10 @@ func (a *API) HTTPTriggerApiDelete(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["httpTrigger"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
err := a.fissionClient.Httptriggers(ns).Delete(name, &api.DeleteOptions{})
|
||||
err := a.fissionClient.HTTPTriggers(ns).Delete(name, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
|
||||
+11
-11
@@ -22,15 +22,15 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (a *API) MessageQueueTriggerApiList(w http.ResponseWriter, r *http.Request) {
|
||||
//mqType := r.FormValue("mqtype") // ignored for now
|
||||
triggers, err := a.fissionClient.Messagequeuetriggers(api.NamespaceAll).List(api.ListOptions{})
|
||||
triggers, err := a.fissionClient.MessageQueueTriggers(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -50,7 +50,7 @@ func (a *API) MessageQueueTriggerApiCreate(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
var mqTrigger tpr.Messagequeuetrigger
|
||||
var mqTrigger crd.MessageQueueTrigger
|
||||
err = json.Unmarshal(body, &mqTrigger)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -63,7 +63,7 @@ func (a *API) MessageQueueTriggerApiCreate(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
tnew, err := a.fissionClient.Messagequeuetriggers(mqTrigger.Metadata.Namespace).Create(&mqTrigger)
|
||||
tnew, err := a.fissionClient.MessageQueueTriggers(mqTrigger.Metadata.Namespace).Create(&mqTrigger)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -83,10 +83,10 @@ func (a *API) MessageQueueTriggerApiGet(w http.ResponseWriter, r *http.Request)
|
||||
name := vars["mqTrigger"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
mqTrigger, err := a.fissionClient.Messagequeuetriggers(ns).Get(name)
|
||||
mqTrigger, err := a.fissionClient.MessageQueueTriggers(ns).Get(name)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -109,7 +109,7 @@ func (a *API) MessageQueueTriggerApiUpdate(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
var mqTrigger tpr.Messagequeuetrigger
|
||||
var mqTrigger crd.MessageQueueTrigger
|
||||
err = json.Unmarshal(body, &mqTrigger)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -122,7 +122,7 @@ func (a *API) MessageQueueTriggerApiUpdate(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
tnew, err := a.fissionClient.Messagequeuetriggers(mqTrigger.Metadata.Namespace).Update(&mqTrigger)
|
||||
tnew, err := a.fissionClient.MessageQueueTriggers(mqTrigger.Metadata.Namespace).Update(&mqTrigger)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -141,10 +141,10 @@ func (a *API) MessageQueueTriggerApiDelete(w http.ResponseWriter, r *http.Reques
|
||||
name := vars["mqTrigger"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
err := a.fissionClient.Messagequeuetriggers(ns).Delete(name, &api.DeleteOptions{})
|
||||
err := a.fissionClient.MessageQueueTriggers(ns).Delete(name, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
|
||||
@@ -22,14 +22,14 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (a *API) PackageApiList(w http.ResponseWriter, r *http.Request) {
|
||||
funcs, err := a.fissionClient.Packages(api.NamespaceAll).List(api.ListOptions{})
|
||||
funcs, err := a.fissionClient.Packages(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -51,7 +51,7 @@ func (a *API) PackageApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var f tpr.Package
|
||||
var f crd.Package
|
||||
err = json.Unmarshal(body, &f)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -97,7 +97,7 @@ func (a *API) PackageApiGet(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["package"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
raw := r.FormValue("raw") // just the deployment pkg
|
||||
|
||||
@@ -130,7 +130,7 @@ func (a *API) PackageApiUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var f tpr.Package
|
||||
var f crd.Package
|
||||
err = json.Unmarshal(body, &f)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -162,10 +162,10 @@ func (a *API) PackageApiDelete(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["package"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
err := a.fissionClient.Packages(ns).Delete(name, &api.DeleteOptions{})
|
||||
err := a.fissionClient.Packages(ns).Delete(name, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
|
||||
@@ -23,14 +23,14 @@ import (
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/robfig/cron"
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (a *API) TimeTriggerApiList(w http.ResponseWriter, r *http.Request) {
|
||||
triggers, err := a.fissionClient.Timetriggers(api.NamespaceAll).List(api.ListOptions{})
|
||||
triggers, err := a.fissionClient.TimeTriggers(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -52,7 +52,7 @@ func (a *API) TimeTriggerApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var t tpr.Timetrigger
|
||||
var t crd.TimeTrigger
|
||||
err = json.Unmarshal(body, &t)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -73,7 +73,7 @@ func (a *API) TimeTriggerApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
tnew, err := a.fissionClient.Timetriggers(t.Metadata.Namespace).Create(&t)
|
||||
tnew, err := a.fissionClient.TimeTriggers(t.Metadata.Namespace).Create(&t)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -94,10 +94,10 @@ func (a *API) TimeTriggerApiGet(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["timeTrigger"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
t, err := a.fissionClient.Timetriggers(ns).Get(name)
|
||||
t, err := a.fissionClient.TimeTriggers(ns).Get(name)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -122,7 +122,7 @@ func (a *API) TimeTriggerApiUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var t tpr.Timetrigger
|
||||
var t crd.TimeTrigger
|
||||
err = json.Unmarshal(body, &t)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -142,7 +142,7 @@ func (a *API) TimeTriggerApiUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
tnew, err := a.fissionClient.Timetriggers(t.Metadata.Namespace).Update(&t)
|
||||
tnew, err := a.fissionClient.TimeTriggers(t.Metadata.Namespace).Update(&t)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -161,10 +161,10 @@ func (a *API) TimeTriggerApiDelete(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["timeTrigger"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
err := a.fissionClient.Timetriggers(ns).Delete(name, &api.DeleteOptions{})
|
||||
err := a.fissionClient.TimeTriggers(ns).Delete(name, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright 2017 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (a *API) Tpr2crdApi(w http.ResponseWriter, r *http.Request) {
|
||||
_, kubeClient, _, err := crd.MakeFissionClient()
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
fissionTprs := []string{
|
||||
"function.fission.io",
|
||||
"environment.fission.io",
|
||||
"httptrigger.fission.io",
|
||||
"kuberneteswatchtrigger.fission.io",
|
||||
"timetrigger.fission.io",
|
||||
"messagequeuetrigger.fission.io",
|
||||
"package.fission.io",
|
||||
}
|
||||
|
||||
tprList, err := kubeClient.ThirdPartyResources().List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, tpr := range tprList.Items {
|
||||
for _, tprName := range fissionTprs {
|
||||
if tpr.Name == tprName {
|
||||
err := kubeClient.ThirdPartyResources().Delete(tpr.Name, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a.respondWithSuccess(w, nil)
|
||||
}
|
||||
@@ -22,14 +22,14 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func (a *API) WatchApiList(w http.ResponseWriter, r *http.Request) {
|
||||
watches, err := a.fissionClient.Kuberneteswatchtriggers(api.NamespaceAll).List(api.ListOptions{})
|
||||
watches, err := a.fissionClient.KubernetesWatchTriggers(metav1.NamespaceAll).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -51,7 +51,7 @@ func (a *API) WatchApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var watch tpr.Kuberneteswatchtrigger
|
||||
var watch crd.KubernetesWatchTrigger
|
||||
err = json.Unmarshal(body, &watch)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
@@ -66,7 +66,7 @@ func (a *API) WatchApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// TODO check for duplicate watches
|
||||
|
||||
wnew, err := a.fissionClient.Kuberneteswatchtriggers(watch.Metadata.Namespace).Create(&watch)
|
||||
wnew, err := a.fissionClient.KubernetesWatchTriggers(watch.Metadata.Namespace).Create(&watch)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -87,10 +87,10 @@ func (a *API) WatchApiGet(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["watch"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
watch, err := a.fissionClient.Kuberneteswatchtriggers(ns).Get(name)
|
||||
watch, err := a.fissionClient.KubernetesWatchTriggers(ns).Get(name)
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
@@ -115,10 +115,10 @@ func (a *API) WatchApiDelete(w http.ResponseWriter, r *http.Request) {
|
||||
name := vars["watch"]
|
||||
ns := vars["namespace"]
|
||||
if len(ns) == 0 {
|
||||
ns = api.NamespaceDefault
|
||||
ns = metav1.NamespaceDefault
|
||||
}
|
||||
|
||||
err := a.fissionClient.Kuberneteswatchtriggers(ns).Delete(name, &api.DeleteOptions{})
|
||||
err := a.fissionClient.KubernetesWatchTriggers(ns).Delete(name, &metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
a.respondWithError(w, err)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func (api *API) WorkflowApiserverProxy(w http.ResponseWriter, r *http.Request) {
|
||||
u := api.workflowApiUrl
|
||||
ssUrl, err := url.Parse(u)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("Error parsing url %v: %v", u, err)
|
||||
http.Error(w, msg, 500)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
path := fmt.Sprintf("/%s", vars["path"])
|
||||
director := func(req *http.Request) {
|
||||
req.URL.Scheme = ssUrl.Scheme
|
||||
req.URL.Host = ssUrl.Host
|
||||
req.URL.Path = path
|
||||
}
|
||||
proxy := &httputil.ReverseProxy{
|
||||
Director: director,
|
||||
}
|
||||
proxy.ServeHTTP(w, r)
|
||||
}
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
Copyright 2016 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package crd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
type (
|
||||
FissionClient struct {
|
||||
crdClient *rest.RESTClient
|
||||
}
|
||||
)
|
||||
|
||||
// Get a kubernetes client using the kubeconfig file at the
|
||||
// environment var $KUBECONFIG, or an in-cluster config if that's
|
||||
// undefined.
|
||||
func GetKubernetesClient() (*rest.Config, *kubernetes.Clientset, *apiextensionsclient.Clientset, error) {
|
||||
var config *rest.Config
|
||||
var err error
|
||||
|
||||
// get the config, either from kubeconfig or using our
|
||||
// in-cluster service account
|
||||
kubeConfig := os.Getenv("KUBECONFIG")
|
||||
if len(kubeConfig) != 0 {
|
||||
config, err = clientcmd.BuildConfigFromFlags("", kubeConfig)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
} else {
|
||||
config, err = rest.InClusterConfig()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// creates the clientset
|
||||
clientset, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
apiExtClientset, err := apiextensionsclient.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
return config, clientset, apiExtClientset, nil
|
||||
}
|
||||
|
||||
// GetCrdClient gets a CRD client config
|
||||
func GetCrdClient(config *rest.Config) (*rest.RESTClient, error) {
|
||||
// mutate config to add our types
|
||||
configureClient(config)
|
||||
|
||||
// make a REST client with that config
|
||||
return rest.RESTClientFor(config)
|
||||
}
|
||||
|
||||
// configureClient sets up a REST client for Fission CRD types.
|
||||
//
|
||||
// This is copied from the client-go CRD example. (I don't understand
|
||||
// all of it completely.) It registers our types with the global API
|
||||
// "scheme" (api.Scheme), which keeps a directory of types [I guess so
|
||||
// it can use the string in the Kind field to make a Go object?]. It
|
||||
// also puts the fission CRD types under a "group version" which we
|
||||
// create for our CRDs types.
|
||||
func configureClient(config *rest.Config) {
|
||||
groupversion := schema.GroupVersion{
|
||||
Group: "fission.io",
|
||||
Version: "v1",
|
||||
}
|
||||
config.GroupVersion = &groupversion
|
||||
config.APIPath = "/apis"
|
||||
config.ContentType = runtime.ContentTypeJSON
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
||||
|
||||
schemeBuilder := runtime.NewSchemeBuilder(
|
||||
func(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(
|
||||
groupversion,
|
||||
&Function{},
|
||||
&FunctionList{},
|
||||
&metav1.ListOptions{},
|
||||
&metav1.DeleteOptions{},
|
||||
)
|
||||
scheme.AddKnownTypes(
|
||||
groupversion,
|
||||
&Environment{},
|
||||
&EnvironmentList{},
|
||||
&metav1.ListOptions{},
|
||||
&metav1.DeleteOptions{},
|
||||
)
|
||||
scheme.AddKnownTypes(
|
||||
groupversion,
|
||||
&HTTPTrigger{},
|
||||
&HTTPTriggerList{},
|
||||
&metav1.ListOptions{},
|
||||
&metav1.DeleteOptions{},
|
||||
)
|
||||
scheme.AddKnownTypes(
|
||||
groupversion,
|
||||
&KubernetesWatchTrigger{},
|
||||
&KubernetesWatchTriggerList{},
|
||||
&metav1.ListOptions{},
|
||||
&metav1.DeleteOptions{},
|
||||
)
|
||||
scheme.AddKnownTypes(
|
||||
groupversion,
|
||||
&TimeTrigger{},
|
||||
&TimeTriggerList{},
|
||||
&metav1.ListOptions{},
|
||||
&metav1.DeleteOptions{},
|
||||
)
|
||||
scheme.AddKnownTypes(
|
||||
groupversion,
|
||||
&MessageQueueTrigger{},
|
||||
&MessageQueueTriggerList{},
|
||||
&metav1.ListOptions{},
|
||||
&metav1.DeleteOptions{},
|
||||
)
|
||||
scheme.AddKnownTypes(
|
||||
groupversion,
|
||||
&Package{},
|
||||
&PackageList{},
|
||||
&metav1.ListOptions{},
|
||||
&metav1.DeleteOptions{},
|
||||
)
|
||||
return nil
|
||||
})
|
||||
schemeBuilder.AddToScheme(scheme.Scheme)
|
||||
}
|
||||
|
||||
func waitForCRDs(crdClient *rest.RESTClient) error {
|
||||
start := time.Now()
|
||||
for {
|
||||
fi := MakeFunctionInterface(crdClient, metav1.NamespaceDefault)
|
||||
_, err := fi.List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if time.Now().Sub(start) > 30*time.Second {
|
||||
return errors.New("timeout waiting for CRDs")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func MakeFissionClient() (*FissionClient, *kubernetes.Clientset, *apiextensionsclient.Clientset, error) {
|
||||
config, kubeClient, apiExtClient, err := GetKubernetesClient()
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
crdClient, err := GetCrdClient(config)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
fc := &FissionClient{
|
||||
crdClient: crdClient,
|
||||
}
|
||||
return fc, kubeClient, apiExtClient, nil
|
||||
}
|
||||
|
||||
func (fc *FissionClient) Functions(ns string) FunctionInterface {
|
||||
return MakeFunctionInterface(fc.crdClient, ns)
|
||||
}
|
||||
func (fc *FissionClient) Environments(ns string) EnvironmentInterface {
|
||||
return MakeEnvironmentInterface(fc.crdClient, ns)
|
||||
}
|
||||
func (fc *FissionClient) HTTPTriggers(ns string) HTTPTriggerInterface {
|
||||
return MakeHTTPTriggerInterface(fc.crdClient, ns)
|
||||
}
|
||||
func (fc *FissionClient) KubernetesWatchTriggers(ns string) KubernetesWatchTriggerInterface {
|
||||
return MakeKubernetesWatchTriggerInterface(fc.crdClient, ns)
|
||||
}
|
||||
func (fc *FissionClient) TimeTriggers(ns string) TimeTriggerInterface {
|
||||
return MakeTimeTriggerInterface(fc.crdClient, ns)
|
||||
}
|
||||
func (fc *FissionClient) MessageQueueTriggers(ns string) MessageQueueTriggerInterface {
|
||||
return MakeMessageQueueTriggerInterface(fc.crdClient, ns)
|
||||
}
|
||||
func (fc *FissionClient) Packages(ns string) PackageInterface {
|
||||
return MakePackageInterface(fc.crdClient, ns)
|
||||
}
|
||||
|
||||
func (fc *FissionClient) WaitForCRDs() {
|
||||
waitForCRDs(fc.crdClient)
|
||||
}
|
||||
func (fc *FissionClient) GetCrdClient() *rest.RESTClient {
|
||||
return fc.crdClient
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
Copyright 2016 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package crd
|
||||
|
||||
import (
|
||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
crdGroupName = "fission.io"
|
||||
crdVersion = "v1"
|
||||
)
|
||||
|
||||
// ensureCRD checks if the given CRD type exists, and creates it if
|
||||
// needed. (Note that this creates the CRD type; it doesn't create any
|
||||
// _instances_ of that type.)
|
||||
func ensureCRD(clientset *apiextensionsclient.Clientset, crd *apiextensionsv1beta1.CustomResourceDefinition) error {
|
||||
_, err := clientset.Apiextensions().CustomResourceDefinitions().Get(crd.ObjectMeta.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
_, err := clientset.Apiextensions().CustomResourceDefinitions().Create(crd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ensure CRDs
|
||||
func EnsureFissionCRDs(clientset *apiextensionsclient.Clientset) error {
|
||||
crds := []apiextensionsv1beta1.CustomResourceDefinition{
|
||||
// Functions
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "functions.fission.io",
|
||||
},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: crdGroupName,
|
||||
Version: crdVersion,
|
||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Kind: "Function",
|
||||
Plural: "functions",
|
||||
Singular: "function",
|
||||
},
|
||||
},
|
||||
},
|
||||
// Environments (function containers)
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "environments.fission.io",
|
||||
},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: crdGroupName,
|
||||
Version: crdVersion,
|
||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Kind: "Environment",
|
||||
Plural: "environments",
|
||||
Singular: "environment",
|
||||
},
|
||||
},
|
||||
},
|
||||
// HTTP triggers for functions
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "httptriggers.fission.io",
|
||||
},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: crdGroupName,
|
||||
Version: crdVersion,
|
||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Kind: "HTTPTrigger",
|
||||
Plural: "httptriggers",
|
||||
Singular: "httptrigger",
|
||||
},
|
||||
},
|
||||
},
|
||||
// Kubernetes watch triggers for functions
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "kuberneteswatchtriggers.fission.io",
|
||||
},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: crdGroupName,
|
||||
Version: crdVersion,
|
||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Kind: "KubernetesWatchTrigger",
|
||||
Plural: "kuberneteswatchtriggers",
|
||||
Singular: "kuberneteswatchtrigger",
|
||||
},
|
||||
},
|
||||
},
|
||||
// Time-based triggers for functions
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "timetriggers.fission.io",
|
||||
},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: crdGroupName,
|
||||
Version: crdVersion,
|
||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Kind: "TimeTrigger",
|
||||
Plural: "timetriggers",
|
||||
Singular: "timetrigger",
|
||||
},
|
||||
},
|
||||
},
|
||||
// Message queue triggers for functions
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "messagequeuetriggers.fission.io",
|
||||
},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: crdGroupName,
|
||||
Version: crdVersion,
|
||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Kind: "MessageQueueTrigger",
|
||||
Plural: "messagequeuetriggers",
|
||||
Singular: "messagequeuetrigger",
|
||||
},
|
||||
},
|
||||
},
|
||||
// Packages: archives containing source or binaries for one or more functions
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "packages.fission.io",
|
||||
},
|
||||
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
|
||||
Group: crdGroupName,
|
||||
Version: crdVersion,
|
||||
Scope: apiextensionsv1beta1.NamespaceScoped,
|
||||
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
|
||||
Kind: "Package",
|
||||
Plural: "packages",
|
||||
Singular: "package",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, crd := range crds {
|
||||
err := ensureCRD(clientset, &crd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tpr
|
||||
package crd
|
||||
|
||||
import (
|
||||
"log"
|
||||
@@ -22,9 +22,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/rest"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
"github.com/fission/fission"
|
||||
)
|
||||
@@ -35,15 +34,16 @@ func panicIf(err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func functionTests(tprClient *rest.RESTClient) {
|
||||
func functionTests(crdClient *rest.RESTClient) {
|
||||
// sample function object
|
||||
function := &Function{
|
||||
TypeMeta: unversioned.TypeMeta{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Function",
|
||||
APIVersion: "fission.io/v1",
|
||||
},
|
||||
Metadata: api.ObjectMeta{
|
||||
Name: "hello",
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "hello",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: fission.FunctionSpec{
|
||||
Package: fission.FunctionPackageRef{
|
||||
@@ -60,7 +60,7 @@ func functionTests(tprClient *rest.RESTClient) {
|
||||
}
|
||||
|
||||
// Test function CRUD
|
||||
fi := MakeFunctionInterface(tprClient, api.NamespaceDefault)
|
||||
fi := MakeFunctionInterface(crdClient, metav1.NamespaceDefault)
|
||||
|
||||
// cleanup from old crashed tests, ignore errors
|
||||
fi.Delete(function.Metadata.Name, nil)
|
||||
@@ -82,6 +82,7 @@ func functionTests(tprClient *rest.RESTClient) {
|
||||
log.Printf("f.Metadata = %#v", f.Metadata)
|
||||
|
||||
// update
|
||||
function.Metadata.ResourceVersion = f.Metadata.ResourceVersion
|
||||
function.Spec.Environment.Name = "yyy"
|
||||
f, err = fi.Update(function)
|
||||
panicIf(err)
|
||||
@@ -89,12 +90,12 @@ func functionTests(tprClient *rest.RESTClient) {
|
||||
log.Printf("f.Metadata = %#v", f.Metadata)
|
||||
|
||||
// list
|
||||
fl, err := fi.List(api.ListOptions{})
|
||||
fl, err := fi.List(metav1.ListOptions{})
|
||||
panicIf(err)
|
||||
if len(fl.Items) != 1 {
|
||||
log.Panicf("wrong count from list: %v", fl)
|
||||
log.Panicf("wrong count from function list: %v", len(fl.Items))
|
||||
}
|
||||
if fl.Items[0].Spec.Environment.Name != function.Spec.Environment.Name {
|
||||
if fl.Items[0].Spec.Environment.Name != f.Spec.Environment.Name {
|
||||
log.Panicf("bad object from list: %v", fl.Items[0])
|
||||
}
|
||||
|
||||
@@ -103,10 +104,11 @@ func functionTests(tprClient *rest.RESTClient) {
|
||||
panicIf(err)
|
||||
|
||||
// start a watch
|
||||
wi, err := fi.Watch(api.ListOptions{})
|
||||
wi, err := fi.Watch(metav1.ListOptions{})
|
||||
panicIf(err)
|
||||
|
||||
start := time.Now()
|
||||
function.Metadata.ResourceVersion = ""
|
||||
f, err = fi.Create(function)
|
||||
panicIf(err)
|
||||
defer fi.Delete(f.Metadata.Name, nil)
|
||||
@@ -132,15 +134,16 @@ func functionTests(tprClient *rest.RESTClient) {
|
||||
|
||||
}
|
||||
|
||||
func environmentTests(tprClient *rest.RESTClient) {
|
||||
func environmentTests(crdClient *rest.RESTClient) {
|
||||
// sample environment object
|
||||
environment := &Environment{
|
||||
TypeMeta: unversioned.TypeMeta{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Environment",
|
||||
APIVersion: "fission.io/v1",
|
||||
},
|
||||
Metadata: api.ObjectMeta{
|
||||
Name: "hello",
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "hello",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: fission.EnvironmentSpec{
|
||||
Runtime: fission.Runtime{
|
||||
@@ -154,7 +157,7 @@ func environmentTests(tprClient *rest.RESTClient) {
|
||||
}
|
||||
|
||||
// Test environment CRUD
|
||||
ei := MakeEnvironmentInterface(tprClient, api.NamespaceDefault)
|
||||
ei := MakeEnvironmentInterface(crdClient, metav1.NamespaceDefault)
|
||||
|
||||
// cleanup from old crashed tests, ignore errors
|
||||
ei.Delete(environment.Metadata.Name, nil)
|
||||
@@ -174,17 +177,18 @@ func environmentTests(tprClient *rest.RESTClient) {
|
||||
}
|
||||
|
||||
// update
|
||||
environment.Metadata.ResourceVersion = e.Metadata.ResourceVersion
|
||||
environment.Spec.Runtime.Image = "www"
|
||||
e, err = ei.Update(environment)
|
||||
panicIf(err)
|
||||
|
||||
// list
|
||||
el, err := ei.List(api.ListOptions{})
|
||||
el, err := ei.List(metav1.ListOptions{})
|
||||
panicIf(err)
|
||||
if len(el.Items) != 1 {
|
||||
log.Panicf("wrong count from list: %v", len(el.Items))
|
||||
log.Panicf("wrong count from environment list: %v", len(el.Items))
|
||||
}
|
||||
if el.Items[0].Spec.Runtime.Image != environment.Spec.Runtime.Image {
|
||||
if el.Items[0].Spec.Runtime.Image != e.Spec.Runtime.Image {
|
||||
log.Panicf("bad object from list: %v", el.Items[0])
|
||||
}
|
||||
|
||||
@@ -193,10 +197,11 @@ func environmentTests(tprClient *rest.RESTClient) {
|
||||
panicIf(err)
|
||||
|
||||
// start a watch
|
||||
wi, err := ei.Watch(api.ListOptions{})
|
||||
wi, err := ei.Watch(metav1.ListOptions{})
|
||||
panicIf(err)
|
||||
|
||||
start := time.Now()
|
||||
environment.Metadata.ResourceVersion = ""
|
||||
e, err = ei.Create(environment)
|
||||
panicIf(err)
|
||||
defer ei.Delete(e.Metadata.Name, nil)
|
||||
@@ -222,15 +227,16 @@ func environmentTests(tprClient *rest.RESTClient) {
|
||||
|
||||
}
|
||||
|
||||
func httpTriggerTests(tprClient *rest.RESTClient) {
|
||||
func httpTriggerTests(crdClient *rest.RESTClient) {
|
||||
// sample httpTrigger object
|
||||
httpTrigger := &Httptrigger{
|
||||
TypeMeta: unversioned.TypeMeta{
|
||||
Kind: "Httptrigger",
|
||||
httpTrigger := &HTTPTrigger{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "HTTPTrigger",
|
||||
APIVersion: "fission.io/v1",
|
||||
},
|
||||
Metadata: api.ObjectMeta{
|
||||
Name: "hello",
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "hello",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: fission.HTTPTriggerSpec{
|
||||
RelativeURL: "/hi",
|
||||
@@ -243,7 +249,7 @@ func httpTriggerTests(tprClient *rest.RESTClient) {
|
||||
}
|
||||
|
||||
// Test httpTrigger CRUD
|
||||
ei := MakeHttptriggerInterface(tprClient, api.NamespaceDefault)
|
||||
ei := MakeHTTPTriggerInterface(crdClient, metav1.NamespaceDefault)
|
||||
|
||||
// cleanup from old crashed tests, ignore errors
|
||||
ei.Delete(httpTrigger.Metadata.Name, nil)
|
||||
@@ -263,17 +269,18 @@ func httpTriggerTests(tprClient *rest.RESTClient) {
|
||||
}
|
||||
|
||||
// update
|
||||
httpTrigger.Metadata.ResourceVersion = e.Metadata.ResourceVersion
|
||||
httpTrigger.Spec.Method = "POST"
|
||||
e, err = ei.Update(httpTrigger)
|
||||
panicIf(err)
|
||||
|
||||
// list
|
||||
el, err := ei.List(api.ListOptions{})
|
||||
el, err := ei.List(metav1.ListOptions{})
|
||||
panicIf(err)
|
||||
if len(el.Items) != 1 {
|
||||
log.Panicf("wrong count from list: %v", el)
|
||||
log.Panicf("wrong count from http trigger list: %v", len(el.Items))
|
||||
}
|
||||
if el.Items[0].Spec.Method != httpTrigger.Spec.Method {
|
||||
if el.Items[0].Spec.Method != e.Spec.Method {
|
||||
log.Panicf("bad object from list: %v", el.Items[0])
|
||||
}
|
||||
|
||||
@@ -282,10 +289,11 @@ func httpTriggerTests(tprClient *rest.RESTClient) {
|
||||
panicIf(err)
|
||||
|
||||
// start a watch
|
||||
wi, err := ei.Watch(api.ListOptions{})
|
||||
wi, err := ei.Watch(metav1.ListOptions{})
|
||||
panicIf(err)
|
||||
|
||||
start := time.Now()
|
||||
httpTrigger.Metadata.ResourceVersion = ""
|
||||
e, err = ei.Create(httpTrigger)
|
||||
panicIf(err)
|
||||
defer ei.Delete(e.Metadata.Name, nil)
|
||||
@@ -298,9 +306,9 @@ func httpTriggerTests(tprClient *rest.RESTClient) {
|
||||
log.Panicf("Didn't get watch event")
|
||||
}
|
||||
case ev := <-wi.ResultChan():
|
||||
obj, ok := ev.Object.(*Httptrigger)
|
||||
obj, ok := ev.Object.(*HTTPTrigger)
|
||||
if !ok {
|
||||
log.Panicf("Can't cast to Httptrigger")
|
||||
log.Panicf("Can't cast to HTTPTrigger")
|
||||
}
|
||||
if obj.Spec.Method != httpTrigger.Spec.Method {
|
||||
log.Panicf("Bad object from watch: %#v", obj)
|
||||
@@ -311,15 +319,16 @@ func httpTriggerTests(tprClient *rest.RESTClient) {
|
||||
|
||||
}
|
||||
|
||||
func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) {
|
||||
func kubernetesWatchTriggerTests(crdClient *rest.RESTClient) {
|
||||
// sample kubernetesWatchTrigger object
|
||||
kubernetesWatchTrigger := &Kuberneteswatchtrigger{
|
||||
TypeMeta: unversioned.TypeMeta{
|
||||
Kind: "Kuberneteswatchtrigger",
|
||||
kubernetesWatchTrigger := &KubernetesWatchTrigger{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "KubernetesWatchTrigger",
|
||||
APIVersion: "fission.io/v1",
|
||||
},
|
||||
Metadata: api.ObjectMeta{
|
||||
Name: "hello",
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "hello",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: fission.KubernetesWatchTriggerSpec{
|
||||
Namespace: "foo",
|
||||
@@ -335,7 +344,7 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) {
|
||||
}
|
||||
|
||||
// Test kubernetesWatchTrigger CRUD
|
||||
ei := MakeKuberneteswatchtriggerInterface(tprClient, api.NamespaceDefault)
|
||||
ei := MakeKubernetesWatchTriggerInterface(crdClient, metav1.NamespaceDefault)
|
||||
|
||||
// cleanup from old crashed tests, ignore errors
|
||||
ei.Delete(kubernetesWatchTrigger.Metadata.Name, nil)
|
||||
@@ -355,17 +364,18 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) {
|
||||
}
|
||||
|
||||
// update
|
||||
kubernetesWatchTrigger.Metadata.ResourceVersion = e.Metadata.ResourceVersion
|
||||
kubernetesWatchTrigger.Spec.Type = "service"
|
||||
e, err = ei.Update(kubernetesWatchTrigger)
|
||||
panicIf(err)
|
||||
|
||||
// list
|
||||
el, err := ei.List(api.ListOptions{})
|
||||
el, err := ei.List(metav1.ListOptions{})
|
||||
panicIf(err)
|
||||
if len(el.Items) != 1 {
|
||||
log.Panicf("wrong count from list: %v", el)
|
||||
log.Panicf("wrong count from kubeWatcher list: %v", len(el.Items))
|
||||
}
|
||||
if el.Items[0].Spec.Type != kubernetesWatchTrigger.Spec.Type {
|
||||
if el.Items[0].Spec.Type != e.Spec.Type {
|
||||
log.Panicf("bad object from list: %v", el.Items[0])
|
||||
}
|
||||
|
||||
@@ -374,10 +384,11 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) {
|
||||
panicIf(err)
|
||||
|
||||
// start a watch
|
||||
wi, err := ei.Watch(api.ListOptions{})
|
||||
wi, err := ei.Watch(metav1.ListOptions{})
|
||||
panicIf(err)
|
||||
|
||||
start := time.Now()
|
||||
kubernetesWatchTrigger.Metadata.ResourceVersion = ""
|
||||
e, err = ei.Create(kubernetesWatchTrigger)
|
||||
panicIf(err)
|
||||
defer ei.Delete(e.Metadata.Name, nil)
|
||||
@@ -390,9 +401,9 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) {
|
||||
log.Panicf("Didn't get watch event")
|
||||
}
|
||||
case ev := <-wi.ResultChan():
|
||||
obj, ok := ev.Object.(*Kuberneteswatchtrigger)
|
||||
obj, ok := ev.Object.(*KubernetesWatchTrigger)
|
||||
if !ok {
|
||||
log.Panicf("Can't cast to Kuberneteswatchtrigger")
|
||||
log.Panicf("Can't cast to KubernetesWatchTrigger")
|
||||
}
|
||||
if obj.Spec.Type != kubernetesWatchTrigger.Spec.Type {
|
||||
log.Panicf("Bad object from watch: %#v", obj)
|
||||
@@ -403,7 +414,7 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) {
|
||||
|
||||
}
|
||||
|
||||
func TestTpr(t *testing.T) {
|
||||
func TestCrd(t *testing.T) {
|
||||
// skip test if no cluster available for testing
|
||||
kubeconfig := os.Getenv("KUBECONFIG")
|
||||
if len(kubeconfig) == 0 {
|
||||
@@ -413,22 +424,22 @@ func TestTpr(t *testing.T) {
|
||||
|
||||
// Create the client config. Needs the KUBECONFIG env var to
|
||||
// point at a valid kubeconfig.
|
||||
config, clientset, err := GetKubernetesClient()
|
||||
config, _, apiExtClient, err := GetKubernetesClient()
|
||||
panicIf(err)
|
||||
|
||||
// init our types
|
||||
err = EnsureFissionTPRs(clientset)
|
||||
err = EnsureFissionCRDs(apiExtClient)
|
||||
panicIf(err)
|
||||
|
||||
// rest client with knowledge about our tpr types
|
||||
tprClient, err := GetTprClient(config)
|
||||
// rest client with knowledge about our crd types
|
||||
crdClient, err := GetCrdClient(config)
|
||||
panicIf(err)
|
||||
|
||||
err = waitForTPRs(tprClient)
|
||||
err = waitForCRDs(crdClient)
|
||||
panicIf(err)
|
||||
|
||||
functionTests(tprClient)
|
||||
environmentTests(tprClient)
|
||||
httpTriggerTests(tprClient)
|
||||
kubernetesWatchTriggerTests(tprClient)
|
||||
functionTests(crdClient)
|
||||
environmentTests(crdClient)
|
||||
httpTriggerTests(crdClient)
|
||||
kubernetesWatchTriggerTests(crdClient)
|
||||
}
|
||||
@@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tpr
|
||||
package crd
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/watch"
|
||||
"k8s.io/client-go/1.5/rest"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -27,9 +28,9 @@ type (
|
||||
Create(*Environment) (*Environment, error)
|
||||
Get(name string) (*Environment, error)
|
||||
Update(*Environment) (*Environment, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
List(opts api.ListOptions) (*EnvironmentList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
List(opts metav1.ListOptions) (*EnvironmentList, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
environmentClient struct {
|
||||
@@ -38,9 +39,9 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func MakeEnvironmentInterface(tprClient *rest.RESTClient, namespace string) EnvironmentInterface {
|
||||
func MakeEnvironmentInterface(crdClient *rest.RESTClient, namespace string) EnvironmentInterface {
|
||||
return &environmentClient{
|
||||
client: tprClient,
|
||||
client: crdClient,
|
||||
namespace: namespace,
|
||||
}
|
||||
}
|
||||
@@ -85,7 +86,7 @@ func (ec *environmentClient) Update(e *Environment) (*Environment, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (ec *environmentClient) Delete(name string, opts *api.DeleteOptions) error {
|
||||
func (ec *environmentClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return ec.client.Delete().
|
||||
Namespace(ec.namespace).
|
||||
Resource("environments").
|
||||
@@ -95,12 +96,12 @@ func (ec *environmentClient) Delete(name string, opts *api.DeleteOptions) error
|
||||
Error()
|
||||
}
|
||||
|
||||
func (ec *environmentClient) List(opts api.ListOptions) (*EnvironmentList, error) {
|
||||
func (ec *environmentClient) List(opts metav1.ListOptions) (*EnvironmentList, error) {
|
||||
var result EnvironmentList
|
||||
err := ec.client.Get().
|
||||
Namespace(ec.namespace).
|
||||
Resource("environments").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(&result)
|
||||
if err != nil {
|
||||
@@ -109,11 +110,11 @@ func (ec *environmentClient) List(opts api.ListOptions) (*EnvironmentList, error
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (ec *environmentClient) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
func (ec *environmentClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return ec.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(ec.namespace).
|
||||
Resource("environments").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
@@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tpr
|
||||
package crd
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/watch"
|
||||
"k8s.io/client-go/1.5/rest"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -27,9 +28,9 @@ type (
|
||||
Create(*Function) (*Function, error)
|
||||
Get(name string) (*Function, error)
|
||||
Update(*Function) (*Function, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
List(opts api.ListOptions) (*FunctionList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
List(opts metav1.ListOptions) (*FunctionList, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
functionClient struct {
|
||||
@@ -38,9 +39,9 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func MakeFunctionInterface(tprClient *rest.RESTClient, namespace string) FunctionInterface {
|
||||
func MakeFunctionInterface(crdClient *rest.RESTClient, namespace string) FunctionInterface {
|
||||
return &functionClient{
|
||||
client: tprClient,
|
||||
client: crdClient,
|
||||
namespace: namespace,
|
||||
}
|
||||
}
|
||||
@@ -85,7 +86,7 @@ func (fc *functionClient) Update(f *Function) (*Function, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (fc *functionClient) Delete(name string, opts *api.DeleteOptions) error {
|
||||
func (fc *functionClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return fc.client.Delete().
|
||||
Namespace(fc.namespace).
|
||||
Resource("functions").
|
||||
@@ -95,12 +96,12 @@ func (fc *functionClient) Delete(name string, opts *api.DeleteOptions) error {
|
||||
Error()
|
||||
}
|
||||
|
||||
func (fc *functionClient) List(opts api.ListOptions) (*FunctionList, error) {
|
||||
func (fc *functionClient) List(opts metav1.ListOptions) (*FunctionList, error) {
|
||||
var result FunctionList
|
||||
err := fc.client.Get().
|
||||
Namespace(fc.namespace).
|
||||
Resource("functions").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(&result)
|
||||
if err != nil {
|
||||
@@ -109,11 +110,11 @@ func (fc *functionClient) List(opts api.ListOptions) (*FunctionList, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (fc *functionClient) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
func (fc *functionClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return fc.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(fc.namespace).
|
||||
Resource("functions").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
@@ -14,22 +14,23 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tpr
|
||||
package crd
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/watch"
|
||||
"k8s.io/client-go/1.5/rest"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type (
|
||||
HttptriggerInterface interface {
|
||||
Create(*Httptrigger) (*Httptrigger, error)
|
||||
Get(name string) (*Httptrigger, error)
|
||||
Update(*Httptrigger) (*Httptrigger, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
List(opts api.ListOptions) (*HttptriggerList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
HTTPTriggerInterface interface {
|
||||
Create(*HTTPTrigger) (*HTTPTrigger, error)
|
||||
Get(name string) (*HTTPTrigger, error)
|
||||
Update(*HTTPTrigger) (*HTTPTrigger, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
List(opts metav1.ListOptions) (*HTTPTriggerList, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
httpTriggerClient struct {
|
||||
@@ -38,15 +39,15 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func MakeHttptriggerInterface(tprClient *rest.RESTClient, namespace string) HttptriggerInterface {
|
||||
func MakeHTTPTriggerInterface(crdClient *rest.RESTClient, namespace string) HTTPTriggerInterface {
|
||||
return &httpTriggerClient{
|
||||
client: tprClient,
|
||||
client: crdClient,
|
||||
namespace: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *httpTriggerClient) Create(obj *Httptrigger) (*Httptrigger, error) {
|
||||
var result Httptrigger
|
||||
func (c *httpTriggerClient) Create(obj *HTTPTrigger) (*HTTPTrigger, error) {
|
||||
var result HTTPTrigger
|
||||
err := c.client.Post().
|
||||
Resource("httptriggers").
|
||||
Namespace(c.namespace).
|
||||
@@ -58,8 +59,8 @@ func (c *httpTriggerClient) Create(obj *Httptrigger) (*Httptrigger, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *httpTriggerClient) Get(name string) (*Httptrigger, error) {
|
||||
var result Httptrigger
|
||||
func (c *httpTriggerClient) Get(name string) (*HTTPTrigger, error) {
|
||||
var result HTTPTrigger
|
||||
err := c.client.Get().
|
||||
Resource("httptriggers").
|
||||
Namespace(c.namespace).
|
||||
@@ -71,8 +72,8 @@ func (c *httpTriggerClient) Get(name string) (*Httptrigger, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *httpTriggerClient) Update(obj *Httptrigger) (*Httptrigger, error) {
|
||||
var result Httptrigger
|
||||
func (c *httpTriggerClient) Update(obj *HTTPTrigger) (*HTTPTrigger, error) {
|
||||
var result HTTPTrigger
|
||||
err := c.client.Put().
|
||||
Resource("httptriggers").
|
||||
Namespace(c.namespace).
|
||||
@@ -85,7 +86,7 @@ func (c *httpTriggerClient) Update(obj *Httptrigger) (*Httptrigger, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *httpTriggerClient) Delete(name string, opts *api.DeleteOptions) error {
|
||||
func (c *httpTriggerClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.namespace).
|
||||
Resource("httptriggers").
|
||||
@@ -95,12 +96,12 @@ func (c *httpTriggerClient) Delete(name string, opts *api.DeleteOptions) error {
|
||||
Error()
|
||||
}
|
||||
|
||||
func (c *httpTriggerClient) List(opts api.ListOptions) (*HttptriggerList, error) {
|
||||
var result HttptriggerList
|
||||
func (c *httpTriggerClient) List(opts metav1.ListOptions) (*HTTPTriggerList, error) {
|
||||
var result HTTPTriggerList
|
||||
err := c.client.Get().
|
||||
Namespace(c.namespace).
|
||||
Resource("httptriggers").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(&result)
|
||||
if err != nil {
|
||||
@@ -109,11 +110,11 @@ func (c *httpTriggerClient) List(opts api.ListOptions) (*HttptriggerList, error)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *httpTriggerClient) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
func (c *httpTriggerClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.namespace).
|
||||
Resource("httptriggers").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
@@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tpr
|
||||
package crd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Given metadata, create a key that uniquely identifies the contents
|
||||
@@ -28,6 +28,6 @@ import (
|
||||
// content. (ResourceVersion may also update on status updates, so
|
||||
// this will result in some unnecessary cache misses. That should be
|
||||
// ok.)
|
||||
func CacheKey(metadata *api.ObjectMeta) string {
|
||||
func CacheKey(metadata *metav1.ObjectMeta) string {
|
||||
return fmt.Sprintf("%v_%v", metadata.UID, metadata.ResourceVersion)
|
||||
}
|
||||
@@ -14,22 +14,23 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tpr
|
||||
package crd
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/watch"
|
||||
"k8s.io/client-go/1.5/rest"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type (
|
||||
KuberneteswatchtriggerInterface interface {
|
||||
Create(*Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error)
|
||||
Get(name string) (*Kuberneteswatchtrigger, error)
|
||||
Update(*Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
List(opts api.ListOptions) (*KuberneteswatchtriggerList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
KubernetesWatchTriggerInterface interface {
|
||||
Create(*KubernetesWatchTrigger) (*KubernetesWatchTrigger, error)
|
||||
Get(name string) (*KubernetesWatchTrigger, error)
|
||||
Update(*KubernetesWatchTrigger) (*KubernetesWatchTrigger, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
List(opts metav1.ListOptions) (*KubernetesWatchTriggerList, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
kubernetesWatchTriggerClient struct {
|
||||
@@ -38,15 +39,15 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func MakeKuberneteswatchtriggerInterface(tprClient *rest.RESTClient, namespace string) KuberneteswatchtriggerInterface {
|
||||
func MakeKubernetesWatchTriggerInterface(crdClient *rest.RESTClient, namespace string) KubernetesWatchTriggerInterface {
|
||||
return &kubernetesWatchTriggerClient{
|
||||
client: tprClient,
|
||||
client: crdClient,
|
||||
namespace: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *kubernetesWatchTriggerClient) Create(obj *Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error) {
|
||||
var result Kuberneteswatchtrigger
|
||||
func (c *kubernetesWatchTriggerClient) Create(obj *KubernetesWatchTrigger) (*KubernetesWatchTrigger, error) {
|
||||
var result KubernetesWatchTrigger
|
||||
err := c.client.Post().
|
||||
Resource("kuberneteswatchtriggers").
|
||||
Namespace(c.namespace).
|
||||
@@ -58,8 +59,8 @@ func (c *kubernetesWatchTriggerClient) Create(obj *Kuberneteswatchtrigger) (*Kub
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *kubernetesWatchTriggerClient) Get(name string) (*Kuberneteswatchtrigger, error) {
|
||||
var result Kuberneteswatchtrigger
|
||||
func (c *kubernetesWatchTriggerClient) Get(name string) (*KubernetesWatchTrigger, error) {
|
||||
var result KubernetesWatchTrigger
|
||||
err := c.client.Get().
|
||||
Resource("kuberneteswatchtriggers").
|
||||
Namespace(c.namespace).
|
||||
@@ -71,8 +72,8 @@ func (c *kubernetesWatchTriggerClient) Get(name string) (*Kuberneteswatchtrigger
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *kubernetesWatchTriggerClient) Update(obj *Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error) {
|
||||
var result Kuberneteswatchtrigger
|
||||
func (c *kubernetesWatchTriggerClient) Update(obj *KubernetesWatchTrigger) (*KubernetesWatchTrigger, error) {
|
||||
var result KubernetesWatchTrigger
|
||||
err := c.client.Put().
|
||||
Resource("kuberneteswatchtriggers").
|
||||
Namespace(c.namespace).
|
||||
@@ -85,7 +86,7 @@ func (c *kubernetesWatchTriggerClient) Update(obj *Kuberneteswatchtrigger) (*Kub
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *kubernetesWatchTriggerClient) Delete(name string, opts *api.DeleteOptions) error {
|
||||
func (c *kubernetesWatchTriggerClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.namespace).
|
||||
Resource("kuberneteswatchtriggers").
|
||||
@@ -95,12 +96,12 @@ func (c *kubernetesWatchTriggerClient) Delete(name string, opts *api.DeleteOptio
|
||||
Error()
|
||||
}
|
||||
|
||||
func (c *kubernetesWatchTriggerClient) List(opts api.ListOptions) (*KuberneteswatchtriggerList, error) {
|
||||
var result KuberneteswatchtriggerList
|
||||
func (c *kubernetesWatchTriggerClient) List(opts metav1.ListOptions) (*KubernetesWatchTriggerList, error) {
|
||||
var result KubernetesWatchTriggerList
|
||||
err := c.client.Get().
|
||||
Namespace(c.namespace).
|
||||
Resource("kuberneteswatchtriggers").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(&result)
|
||||
if err != nil {
|
||||
@@ -109,11 +110,11 @@ func (c *kubernetesWatchTriggerClient) List(opts api.ListOptions) (*Kuberneteswa
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *kubernetesWatchTriggerClient) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
func (c *kubernetesWatchTriggerClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.namespace).
|
||||
Resource("kuberneteswatchtriggers").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
@@ -14,39 +14,40 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tpr
|
||||
package crd
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/watch"
|
||||
"k8s.io/client-go/1.5/rest"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type (
|
||||
MessagequeuetriggerInterface interface {
|
||||
Create(*Messagequeuetrigger) (*Messagequeuetrigger, error)
|
||||
Get(name string) (*Messagequeuetrigger, error)
|
||||
Update(*Messagequeuetrigger) (*Messagequeuetrigger, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
List(opts api.ListOptions) (*MessagequeuetriggerList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
MessageQueueTriggerInterface interface {
|
||||
Create(*MessageQueueTrigger) (*MessageQueueTrigger, error)
|
||||
Get(name string) (*MessageQueueTrigger, error)
|
||||
Update(*MessageQueueTrigger) (*MessageQueueTrigger, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
List(opts metav1.ListOptions) (*MessageQueueTriggerList, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
messagequeuetriggerClient struct {
|
||||
messageQueueTriggerClient struct {
|
||||
client *rest.RESTClient
|
||||
namespace string
|
||||
}
|
||||
)
|
||||
|
||||
func MakeMessagequeuetriggerInterface(tprClient *rest.RESTClient, namespace string) MessagequeuetriggerInterface {
|
||||
return &messagequeuetriggerClient{
|
||||
client: tprClient,
|
||||
func MakeMessageQueueTriggerInterface(crdClient *rest.RESTClient, namespace string) MessageQueueTriggerInterface {
|
||||
return &messageQueueTriggerClient{
|
||||
client: crdClient,
|
||||
namespace: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
func (fc *messagequeuetriggerClient) Create(f *Messagequeuetrigger) (*Messagequeuetrigger, error) {
|
||||
var result Messagequeuetrigger
|
||||
func (fc *messageQueueTriggerClient) Create(f *MessageQueueTrigger) (*MessageQueueTrigger, error) {
|
||||
var result MessageQueueTrigger
|
||||
err := fc.client.Post().
|
||||
Resource("messagequeuetriggers").
|
||||
Namespace(fc.namespace).
|
||||
@@ -58,8 +59,8 @@ func (fc *messagequeuetriggerClient) Create(f *Messagequeuetrigger) (*Messageque
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (fc *messagequeuetriggerClient) Get(name string) (*Messagequeuetrigger, error) {
|
||||
var result Messagequeuetrigger
|
||||
func (fc *messageQueueTriggerClient) Get(name string) (*MessageQueueTrigger, error) {
|
||||
var result MessageQueueTrigger
|
||||
err := fc.client.Get().
|
||||
Resource("messagequeuetriggers").
|
||||
Namespace(fc.namespace).
|
||||
@@ -71,8 +72,8 @@ func (fc *messagequeuetriggerClient) Get(name string) (*Messagequeuetrigger, err
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (fc *messagequeuetriggerClient) Update(f *Messagequeuetrigger) (*Messagequeuetrigger, error) {
|
||||
var result Messagequeuetrigger
|
||||
func (fc *messageQueueTriggerClient) Update(f *MessageQueueTrigger) (*MessageQueueTrigger, error) {
|
||||
var result MessageQueueTrigger
|
||||
err := fc.client.Put().
|
||||
Resource("messagequeuetriggers").
|
||||
Namespace(fc.namespace).
|
||||
@@ -85,7 +86,7 @@ func (fc *messagequeuetriggerClient) Update(f *Messagequeuetrigger) (*Messageque
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (fc *messagequeuetriggerClient) Delete(name string, opts *api.DeleteOptions) error {
|
||||
func (fc *messageQueueTriggerClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return fc.client.Delete().
|
||||
Namespace(fc.namespace).
|
||||
Resource("messagequeuetriggers").
|
||||
@@ -95,12 +96,12 @@ func (fc *messagequeuetriggerClient) Delete(name string, opts *api.DeleteOptions
|
||||
Error()
|
||||
}
|
||||
|
||||
func (fc *messagequeuetriggerClient) List(opts api.ListOptions) (*MessagequeuetriggerList, error) {
|
||||
var result MessagequeuetriggerList
|
||||
func (fc *messageQueueTriggerClient) List(opts metav1.ListOptions) (*MessageQueueTriggerList, error) {
|
||||
var result MessageQueueTriggerList
|
||||
err := fc.client.Get().
|
||||
Namespace(fc.namespace).
|
||||
Resource("messagequeuetriggers").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(&result)
|
||||
if err != nil {
|
||||
@@ -109,11 +110,11 @@ func (fc *messagequeuetriggerClient) List(opts api.ListOptions) (*Messagequeuetr
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (fc *messagequeuetriggerClient) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
func (fc *messageQueueTriggerClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return fc.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(fc.namespace).
|
||||
Resource("messagequeuetriggers").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
@@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tpr
|
||||
package crd
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/watch"
|
||||
"k8s.io/client-go/1.5/rest"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -27,9 +28,9 @@ type (
|
||||
Create(*Package) (*Package, error)
|
||||
Get(name string) (*Package, error)
|
||||
Update(*Package) (*Package, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
List(opts api.ListOptions) (*PackageList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
List(opts metav1.ListOptions) (*PackageList, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
packageClient struct {
|
||||
@@ -38,9 +39,9 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func MakePackageInterface(tprClient *rest.RESTClient, namespace string) PackageInterface {
|
||||
func MakePackageInterface(crdClient *rest.RESTClient, namespace string) PackageInterface {
|
||||
return &packageClient{
|
||||
client: tprClient,
|
||||
client: crdClient,
|
||||
namespace: namespace,
|
||||
}
|
||||
}
|
||||
@@ -85,7 +86,7 @@ func (c *packageClient) Update(f *Package) (*Package, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *packageClient) Delete(name string, opts *api.DeleteOptions) error {
|
||||
func (c *packageClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.namespace).
|
||||
Resource("packages").
|
||||
@@ -95,12 +96,12 @@ func (c *packageClient) Delete(name string, opts *api.DeleteOptions) error {
|
||||
Error()
|
||||
}
|
||||
|
||||
func (c *packageClient) List(opts api.ListOptions) (*PackageList, error) {
|
||||
func (c *packageClient) List(opts metav1.ListOptions) (*PackageList, error) {
|
||||
var result PackageList
|
||||
err := c.client.Get().
|
||||
Namespace(c.namespace).
|
||||
Resource("packages").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(&result)
|
||||
if err != nil {
|
||||
@@ -109,11 +110,11 @@ func (c *packageClient) List(opts api.ListOptions) (*PackageList, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *packageClient) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
func (c *packageClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.namespace).
|
||||
Resource("packages").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
@@ -14,39 +14,40 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package tpr
|
||||
package crd
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/watch"
|
||||
"k8s.io/client-go/1.5/rest"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type (
|
||||
TimetriggerInterface interface {
|
||||
Create(*Timetrigger) (*Timetrigger, error)
|
||||
Get(name string) (*Timetrigger, error)
|
||||
Update(*Timetrigger) (*Timetrigger, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
List(opts api.ListOptions) (*TimetriggerList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
TimeTriggerInterface interface {
|
||||
Create(*TimeTrigger) (*TimeTrigger, error)
|
||||
Get(name string) (*TimeTrigger, error)
|
||||
Update(*TimeTrigger) (*TimeTrigger, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
List(opts metav1.ListOptions) (*TimeTriggerList, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
}
|
||||
|
||||
timetriggerClient struct {
|
||||
timeTriggerClient struct {
|
||||
client *rest.RESTClient
|
||||
namespace string
|
||||
}
|
||||
)
|
||||
|
||||
func MakeTimetriggerInterface(tprClient *rest.RESTClient, namespace string) TimetriggerInterface {
|
||||
return &timetriggerClient{
|
||||
client: tprClient,
|
||||
func MakeTimeTriggerInterface(crdClient *rest.RESTClient, namespace string) TimeTriggerInterface {
|
||||
return &timeTriggerClient{
|
||||
client: crdClient,
|
||||
namespace: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
func (fc *timetriggerClient) Create(f *Timetrigger) (*Timetrigger, error) {
|
||||
var result Timetrigger
|
||||
func (fc *timeTriggerClient) Create(f *TimeTrigger) (*TimeTrigger, error) {
|
||||
var result TimeTrigger
|
||||
err := fc.client.Post().
|
||||
Resource("timetriggers").
|
||||
Namespace(fc.namespace).
|
||||
@@ -58,8 +59,8 @@ func (fc *timetriggerClient) Create(f *Timetrigger) (*Timetrigger, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (fc *timetriggerClient) Get(name string) (*Timetrigger, error) {
|
||||
var result Timetrigger
|
||||
func (fc *timeTriggerClient) Get(name string) (*TimeTrigger, error) {
|
||||
var result TimeTrigger
|
||||
err := fc.client.Get().
|
||||
Resource("timetriggers").
|
||||
Namespace(fc.namespace).
|
||||
@@ -71,8 +72,8 @@ func (fc *timetriggerClient) Get(name string) (*Timetrigger, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (fc *timetriggerClient) Update(f *Timetrigger) (*Timetrigger, error) {
|
||||
var result Timetrigger
|
||||
func (fc *timeTriggerClient) Update(f *TimeTrigger) (*TimeTrigger, error) {
|
||||
var result TimeTrigger
|
||||
err := fc.client.Put().
|
||||
Resource("timetriggers").
|
||||
Namespace(fc.namespace).
|
||||
@@ -85,7 +86,7 @@ func (fc *timetriggerClient) Update(f *Timetrigger) (*Timetrigger, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (fc *timetriggerClient) Delete(name string, opts *api.DeleteOptions) error {
|
||||
func (fc *timeTriggerClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return fc.client.Delete().
|
||||
Namespace(fc.namespace).
|
||||
Resource("timetriggers").
|
||||
@@ -95,12 +96,12 @@ func (fc *timetriggerClient) Delete(name string, opts *api.DeleteOptions) error
|
||||
Error()
|
||||
}
|
||||
|
||||
func (fc *timetriggerClient) List(opts api.ListOptions) (*TimetriggerList, error) {
|
||||
var result TimetriggerList
|
||||
func (fc *timeTriggerClient) List(opts metav1.ListOptions) (*TimeTriggerList, error) {
|
||||
var result TimeTriggerList
|
||||
err := fc.client.Get().
|
||||
Namespace(fc.namespace).
|
||||
Resource("timetriggers").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(&result)
|
||||
if err != nil {
|
||||
@@ -109,11 +110,11 @@ func (fc *timetriggerClient) List(opts api.ListOptions) (*TimetriggerList, error
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (fc *timetriggerClient) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
func (fc *timeTriggerClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return fc.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(fc.namespace).
|
||||
Resource("timetriggers").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
Copyright 2016 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package crd
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/fission/fission"
|
||||
)
|
||||
|
||||
//
|
||||
// To add a Fission CRD type:
|
||||
// 1. Create a "spec" type, for everything in the type except metadata
|
||||
// 2. Create the type with metadata + the spec
|
||||
// 3. Create a list type (for example see FunctionList and Function, below)
|
||||
// 4. Add methods at the bottom of this file for satisfying Object and List interfaces
|
||||
// 5. Add the type to configureClient in client.go
|
||||
// 6. Add the type to EnsureFissionCRDs in crd.go
|
||||
// 7. Add tests to crd_test.go
|
||||
// 8. Add a CRUD Interface type (analogous to FunctionInterface in function.go)
|
||||
// 9. Add a getter method for your interface type to FissionClient in client.go
|
||||
//
|
||||
|
||||
type (
|
||||
// Packages. Think of these as function-level images.
|
||||
Package struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ObjectMeta `json:"metadata"`
|
||||
Spec fission.PackageSpec `json:"spec"`
|
||||
|
||||
Status fission.PackageStatus `json:"status"`
|
||||
}
|
||||
PackageList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []Package `json:"items"`
|
||||
}
|
||||
|
||||
// Functions.
|
||||
Function struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ObjectMeta `json:"metadata"`
|
||||
Spec fission.FunctionSpec `json:"spec"`
|
||||
}
|
||||
FunctionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []Function `json:"items"`
|
||||
}
|
||||
|
||||
// Environments.
|
||||
Environment struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ObjectMeta `json:"metadata"`
|
||||
Spec fission.EnvironmentSpec `json:"spec"`
|
||||
}
|
||||
EnvironmentList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []Environment `json:"items"`
|
||||
}
|
||||
|
||||
HTTPTrigger struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ObjectMeta `json:"metadata"`
|
||||
Spec fission.HTTPTriggerSpec `json:"spec"`
|
||||
}
|
||||
HTTPTriggerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []HTTPTrigger `json:"items"`
|
||||
}
|
||||
|
||||
// Kubernetes Watches as triggers
|
||||
KubernetesWatchTrigger struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ObjectMeta `json:"metadata"`
|
||||
Spec fission.KubernetesWatchTriggerSpec `json:"spec"`
|
||||
}
|
||||
KubernetesWatchTriggerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []KubernetesWatchTrigger `json:"items"`
|
||||
}
|
||||
|
||||
// Time triggers
|
||||
TimeTrigger struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ObjectMeta `json:"metadata"`
|
||||
Spec fission.TimeTriggerSpec `json:"spec"`
|
||||
}
|
||||
TimeTriggerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []TimeTrigger `json:"items"`
|
||||
}
|
||||
|
||||
// Message Queue triggers
|
||||
MessageQueueTrigger struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ObjectMeta `json:"metadata"`
|
||||
Spec fission.MessageQueueTriggerSpec `json:"spec"`
|
||||
}
|
||||
MessageQueueTriggerList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
Metadata metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []MessageQueueTrigger `json:"items"`
|
||||
}
|
||||
)
|
||||
|
||||
// Each CRD type needs:
|
||||
// GetObjectKind (to satisfy the Object interface)
|
||||
//
|
||||
// In addition, each singular CRD type needs:
|
||||
// GetObjectMeta (to satisfy the ObjectMetaAccessor interface)
|
||||
//
|
||||
// And each list CRD type needs:
|
||||
// GetListMeta (to satisfy the ListMetaAccessor interface)
|
||||
|
||||
func (f *Function) GetObjectKind() schema.ObjectKind {
|
||||
return &f.TypeMeta
|
||||
}
|
||||
func (e *Environment) GetObjectKind() schema.ObjectKind {
|
||||
return &e.TypeMeta
|
||||
}
|
||||
func (ht *HTTPTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &ht.TypeMeta
|
||||
}
|
||||
func (w *KubernetesWatchTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &w.TypeMeta
|
||||
}
|
||||
func (w *TimeTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &w.TypeMeta
|
||||
}
|
||||
func (w *MessageQueueTrigger) GetObjectKind() schema.ObjectKind {
|
||||
return &w.TypeMeta
|
||||
}
|
||||
func (w *Package) GetObjectKind() schema.ObjectKind {
|
||||
return &w.TypeMeta
|
||||
}
|
||||
|
||||
func (f *Function) GetObjectMeta() metav1.Object {
|
||||
return &f.Metadata
|
||||
}
|
||||
func (e *Environment) GetObjectMeta() metav1.Object {
|
||||
return &e.Metadata
|
||||
}
|
||||
func (ht *HTTPTrigger) GetObjectMeta() metav1.Object {
|
||||
return &ht.Metadata
|
||||
}
|
||||
func (w *KubernetesWatchTrigger) GetObjectMeta() metav1.Object {
|
||||
return &w.Metadata
|
||||
}
|
||||
func (w *TimeTrigger) GetObjectMeta() metav1.Object {
|
||||
return &w.Metadata
|
||||
}
|
||||
func (w *MessageQueueTrigger) GetObjectMeta() metav1.Object {
|
||||
return &w.Metadata
|
||||
}
|
||||
func (w *Package) GetObjectMeta() metav1.Object {
|
||||
return &w.Metadata
|
||||
}
|
||||
|
||||
func (fl *FunctionList) GetObjectKind() schema.ObjectKind {
|
||||
return &fl.TypeMeta
|
||||
}
|
||||
func (el *EnvironmentList) GetObjectKind() schema.ObjectKind {
|
||||
return &el.TypeMeta
|
||||
}
|
||||
func (hl *HTTPTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &hl.TypeMeta
|
||||
}
|
||||
func (wl *KubernetesWatchTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &wl.TypeMeta
|
||||
}
|
||||
func (wl *TimeTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &wl.TypeMeta
|
||||
}
|
||||
func (wl *MessageQueueTriggerList) GetObjectKind() schema.ObjectKind {
|
||||
return &wl.TypeMeta
|
||||
}
|
||||
func (wl *PackageList) GetObjectKind() schema.ObjectKind {
|
||||
return &wl.TypeMeta
|
||||
}
|
||||
|
||||
func (fl *FunctionList) GetListMeta() metav1.List {
|
||||
return &fl.Metadata
|
||||
}
|
||||
func (el *EnvironmentList) GetListMeta() metav1.List {
|
||||
return &el.Metadata
|
||||
}
|
||||
func (hl *HTTPTriggerList) GetListMeta() metav1.List {
|
||||
return &hl.Metadata
|
||||
}
|
||||
func (wl *KubernetesWatchTriggerList) GetListMeta() metav1.List {
|
||||
return &wl.Metadata
|
||||
}
|
||||
func (wl *TimeTriggerList) GetListMeta() metav1.List {
|
||||
return &wl.Metadata
|
||||
}
|
||||
func (wl *MessageQueueTriggerList) GetListMeta() metav1.List {
|
||||
return &wl.Metadata
|
||||
}
|
||||
func (wl *PackageList) GetListMeta() metav1.List {
|
||||
return &wl.Metadata
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
FROM microsoft/dotnet:2.0-runtime
|
||||
|
||||
WORKDIR /fission-workdir
|
||||
COPY out .
|
||||
EXPOSE 8888
|
||||
|
||||
ENTRYPOINT ["dotnet"]
|
||||
|
||||
CMD ["fission-dotnet20.dll"]
|
||||
@@ -0,0 +1,82 @@
|
||||
using Fission.DotNetCore.Compiler;
|
||||
using Fission.DotNetCore.Api;
|
||||
using System.Collections.Generic;
|
||||
using Nancy;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
namespace Fission.DotNetCore
|
||||
{
|
||||
public class ExecutorModule : NancyModule
|
||||
{
|
||||
#if DEBUG
|
||||
private const string CODE_PATH = "/tmp/func.cs";
|
||||
#else
|
||||
private const string CODE_PATH = "/userfunc/user";
|
||||
#endif
|
||||
private static Function _userFunc;
|
||||
private static Logger _logger = new Logger();
|
||||
|
||||
public ExecutorModule()
|
||||
{
|
||||
Post("/specialize", args => Specialize());
|
||||
Get("/", _ => Run());
|
||||
Post("/", _ => Run());
|
||||
Put("/", _ => Run());
|
||||
Head("/", _ => Run());
|
||||
Options("/", _ => Run());
|
||||
Delete("/", _ => Run());
|
||||
}
|
||||
|
||||
private object Specialize()
|
||||
{
|
||||
var errors = new List<string>();
|
||||
if (File.Exists(CODE_PATH))
|
||||
{
|
||||
var code = File.ReadAllText(CODE_PATH);
|
||||
_userFunc = FissionCompiler.Compile(code, out errors);
|
||||
if (_userFunc == null)
|
||||
{
|
||||
var errstr = string.Join(Environment.NewLine, errors);
|
||||
_logger.WriteError(errstr);
|
||||
var response = (Response)errstr;
|
||||
response.StatusCode = HttpStatusCode.InternalServerError;
|
||||
return response;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
var errstr = $"Unable to locate code at '{CODE_PATH}'";
|
||||
_logger.WriteError(errstr);
|
||||
var response = (Response)errstr;
|
||||
response.StatusCode = HttpStatusCode.InternalServerError;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
private object Run()
|
||||
{
|
||||
if (_userFunc == null)
|
||||
{
|
||||
var response = (Response)"Generic container: no requests supported";
|
||||
response.StatusCode = HttpStatusCode.InternalServerError;
|
||||
return response;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return _userFunc.Invoke(FissionContext.Build(Request, new Logger()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.WriteError(e.ToString());
|
||||
var response = (Response)e.Message;
|
||||
response.StatusCode = HttpStatusCode.BadRequest;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Emit;
|
||||
|
||||
namespace Fission.DotNetCore.Compiler
|
||||
{
|
||||
//adapted from this article http://www.tugberkugurlu.com/archive/compiling-c-sharp-code-into-memory-and-executing-it-with-roslyn
|
||||
class FissionCompiler
|
||||
{
|
||||
public static Function Compile(string code, out List<string> errors)
|
||||
{
|
||||
errors = new List<string>();
|
||||
|
||||
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
|
||||
|
||||
string assemblyName = Path.GetRandomFileName();
|
||||
|
||||
var coreDir = Directory.GetParent(typeof(Enumerable).GetTypeInfo().Assembly.Location);
|
||||
|
||||
List<MetadataReference> references = new List<MetadataReference>
|
||||
{
|
||||
MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "mscorlib.dll"),
|
||||
MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
|
||||
MetadataReference.CreateFromFile(Assembly.GetEntryAssembly().Location),
|
||||
MetadataReference.CreateFromFile(typeof(System.Runtime.Serialization.Json.DataContractJsonSerializer).GetTypeInfo().Assembly.Location)
|
||||
};
|
||||
|
||||
foreach (var referencedAssembly in Assembly.GetEntryAssembly().GetReferencedAssemblies())
|
||||
{
|
||||
var assembly = Assembly.Load(referencedAssembly);
|
||||
references.Add(MetadataReference.CreateFromFile(assembly.Location));
|
||||
}
|
||||
|
||||
CSharpCompilation compilation = CSharpCompilation.Create(
|
||||
assemblyName,
|
||||
syntaxTrees: new[] { syntaxTree },
|
||||
references: references,
|
||||
options: new CSharpCompilationOptions(
|
||||
OutputKind.DynamicallyLinkedLibrary,
|
||||
optimizationLevel: OptimizationLevel.Release));
|
||||
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
EmitResult result = compilation.Emit(ms);
|
||||
|
||||
if (!result.Success)
|
||||
{
|
||||
IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
|
||||
diagnostic.IsWarningAsError ||
|
||||
diagnostic.Severity == DiagnosticSeverity.Error).ToList();
|
||||
|
||||
foreach (Diagnostic diagnostic in failures)
|
||||
{
|
||||
errors.Add($"{diagnostic.Id}: {diagnostic.GetMessage()}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
|
||||
var type = assembly.GetType("FissionFunction");
|
||||
var info = type.GetMember("Execute").First() as MethodInfo;
|
||||
return new Function(assembly, type, info);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using Nancy;
|
||||
|
||||
namespace Fission.DotNetCore.Api
|
||||
{
|
||||
public class FissionContext
|
||||
{
|
||||
public FissionContext(Dictionary<string, object> args, Logger logger, FissionHttpRequest request)
|
||||
{
|
||||
if (args == null) throw new ArgumentNullException(nameof(args));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
Arguments = args;
|
||||
Logger = logger;
|
||||
Request = request;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> Arguments { get; private set; }
|
||||
|
||||
public FissionHttpRequest Request { get; private set; }
|
||||
|
||||
public Logger Logger { get; private set; }
|
||||
|
||||
public static FissionContext Build(Request request, Logger logger)
|
||||
{
|
||||
return new FissionContext(((DynamicDictionary)request.Query).ToDictionary(),
|
||||
logger,
|
||||
new FissionHttpRequest(request));
|
||||
}
|
||||
}
|
||||
|
||||
public class Logger
|
||||
{
|
||||
public void Write(Severity severity, string format, params object[] args)
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now.ToString("MM/dd/yy H:mm:ss zzz")} {severity}: " + format, args);
|
||||
}
|
||||
|
||||
public void WriteInfo(string format, params object[] args)
|
||||
{
|
||||
Write(Severity.Info, format, args);
|
||||
}
|
||||
|
||||
public void WriteWarning(string format, params object[] args)
|
||||
{
|
||||
Write(Severity.Warning, format, args);
|
||||
}
|
||||
|
||||
public void WriteError(string format, params object[] args)
|
||||
{
|
||||
Write(Severity.Error, format, args);
|
||||
}
|
||||
|
||||
public void WriteCritical(string format, params object[] args)
|
||||
{
|
||||
Write(Severity.Critical, format, args);
|
||||
}
|
||||
|
||||
public void WriteVerbose(string format, params object[] args)
|
||||
{
|
||||
Write(Severity.Verbose, format, args);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Severity
|
||||
{
|
||||
Info,
|
||||
Warning,
|
||||
Error,
|
||||
Critical,
|
||||
Verbose
|
||||
}
|
||||
|
||||
public class FissionHttpRequest
|
||||
{
|
||||
private readonly Request _request;
|
||||
internal FissionHttpRequest(Request request)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
_request = request;
|
||||
}
|
||||
|
||||
public Stream Body { get { return _request.Body; } }
|
||||
|
||||
public string BodyAsString()
|
||||
{
|
||||
int length = (int)_request.Body.Length;
|
||||
byte[] data = new byte[length];
|
||||
_request.Body.Read(data, 0, length);
|
||||
return Encoding.UTF8.GetString(data);
|
||||
}
|
||||
|
||||
public Dictionary<string, IEnumerable<string>> Headers
|
||||
{
|
||||
get
|
||||
{
|
||||
var headers = new Dictionary<string, IEnumerable<string>>();
|
||||
foreach (var kv in _request.Headers)
|
||||
{
|
||||
headers.Add(kv.Key, kv.Value);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
|
||||
public X509Certificate Certificate { get { return _request.ClientCertificate; } }
|
||||
public string Url { get { return _request.Url.ToString(); } }
|
||||
public string Method { get { return _request.Method; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
namespace Fission.DotNetCore.Compiler
|
||||
{
|
||||
class Function
|
||||
{
|
||||
private readonly Assembly _assembly;
|
||||
private readonly Type _type;
|
||||
private readonly MethodInfo _info;
|
||||
|
||||
public Function(Assembly assembly, Type type, MethodInfo info)
|
||||
{
|
||||
if (info == null) throw new ArgumentNullException(nameof(info));
|
||||
if (assembly == null) throw new ArgumentNullException(nameof(assembly));
|
||||
if (type == null) throw new ArgumentNullException(nameof(type));
|
||||
_assembly = assembly;
|
||||
_type = type;
|
||||
_info = info;
|
||||
}
|
||||
|
||||
public object Invoke(FissionContext context)
|
||||
{
|
||||
return _info.Invoke(_assembly.CreateInstance(_type.FullName), new[] { context });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Nancy.Owin;
|
||||
|
||||
namespace Fission.DotNetCore
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseKestrel()
|
||||
.UseUrls("http://*:8888")
|
||||
.Configure(app => app.UseOwin(x => x.UseNancy()))
|
||||
.Build();
|
||||
host.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
# Fission: dotnet 2.0 C# Environment
|
||||
|
||||
This is a simple dotnet core 2.0 C# environment for Fission.
|
||||
|
||||
It's a Docker image containing the dotnet 2.0.0 runtime. The image
|
||||
uses Kestrel with Nancy to host the internal web server and uses
|
||||
Roslyn to compile the uploaded code.
|
||||
|
||||
The image supports compiling and running code with types defined in
|
||||
mscorlib and does not at present support other library references.
|
||||
One workaround for this would be to add the references to this project's
|
||||
project.json file and rebuild the container.
|
||||
|
||||
The environment works via convention where you create a C# class
|
||||
called FissionFunction which has a method named Execute taking a single
|
||||
parameter, a FissionContext object.
|
||||
|
||||
The FissionContext object gives access to the arguments and other items
|
||||
like logging. Please see FissionContext.cs for public API.
|
||||
|
||||
Example of simplest possible class to be executed:
|
||||
|
||||
```
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction {
|
||||
public string Execute(FissionContext context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Please see examples below.
|
||||
|
||||
## Rebuilding and pushing the image
|
||||
|
||||
To rebuild the image you need either a computer with dotnet core 2.0.0
|
||||
installed or else you will have to map the source directory into a
|
||||
container containing the dotnet core 2.0.0 environment.
|
||||
|
||||
### Locally installed Dotnet core 2.0.0
|
||||
|
||||
Simply move to the source directory in a terminal and run the ./build.sh script.
|
||||
|
||||
The script will restore dependencies, compile a release build and
|
||||
and build the container. If you need to change the name of the container
|
||||
simply change it in the script.
|
||||
|
||||
After the build finishes push the new image to a Docker registry using the
|
||||
standard procedure.
|
||||
|
||||
### Build in a container
|
||||
|
||||
Move to the directory containing the source and start the Docker container
|
||||
with dotnet and mount the current directory to a build location:
|
||||
|
||||
```
|
||||
docker run -it --rm -v $PWD:/build microsoft/dotnet
|
||||
```
|
||||
|
||||
Move to the build directory inside the container and restore the packages:
|
||||
|
||||
```
|
||||
cd /build
|
||||
dotnet restore fission-dotnet20.csproj
|
||||
log : Restoring packages for /source/project.json...
|
||||
log : Installing System.Net.WebSockets 4.0.0.
|
||||
log : Installing runtime.native.System.IO.Compression 4.1.0.
|
||||
...
|
||||
```
|
||||
|
||||
Compile and publish a release build of the source to the 'out' folder:
|
||||
|
||||
```
|
||||
dotnet publish -c Release -o out
|
||||
Publishing source for .NETCoreApp,Version
|
||||
...
|
||||
```
|
||||
Exit the build container and build the Docker container on the local host:
|
||||
|
||||
```
|
||||
exit
|
||||
docker build -t USER/dotnet20-env .
|
||||
```
|
||||
After the build finishes push the new image to a Docker registry using the
|
||||
standard procedure.
|
||||
|
||||
## Echo example
|
||||
|
||||
### Setup fission environment
|
||||
First you need to setup the fission according to your cluster setup as
|
||||
specified here: https://github.com/fission/fission
|
||||
|
||||
|
||||
### Create the class to run
|
||||
|
||||
Secondly you need to create a file /tmp/func.cs containing the following code:
|
||||
|
||||
```
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
context.Logger.WriteInfo("executing.. {0}", context.Arguments["text"]);
|
||||
return (string)context.Arguments["text"];
|
||||
}
|
||||
}
|
||||
```
|
||||
### Run the example
|
||||
|
||||
Lastly to run the example:
|
||||
|
||||
```
|
||||
$ fission env create --name dotnet --image fission/dotnet20-env
|
||||
|
||||
$ fission function create --name echo --env dotnet --code /tmp/func.cs
|
||||
|
||||
$ fission route create --method GET --url /echo --function echo
|
||||
|
||||
$ curl http://$FISSION_ROUTER/echo?text=hello%20world!
|
||||
hello world
|
||||
```
|
||||
|
||||
## Addition service example
|
||||
|
||||
### Setup fission environment
|
||||
First you need to setup the fission according to your cluster setup as
|
||||
specified here: https://github.com/fission/fission
|
||||
|
||||
|
||||
### Create the class to run
|
||||
|
||||
Secondly you need to create a file /tmp/func.cs containing the following code:
|
||||
|
||||
```
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
var x = Convert.ToInt32(context.Arguments["x"]);
|
||||
var y = Convert.ToInt32(context.Arguments["y"]);
|
||||
return (x+y).ToString();
|
||||
}
|
||||
}
|
||||
```
|
||||
### Run the example
|
||||
|
||||
Lastly to run the example:
|
||||
|
||||
```
|
||||
$ fission env create --name dotnet --image fission/dotnet20-env
|
||||
|
||||
$ fission function create --name addition --env dotnet --code /tmp/func.cs
|
||||
|
||||
$ fission route create --method GET --url /add --function addition
|
||||
|
||||
$ curl "http://$FISSION_ROUTER/add?x=30&y=12"
|
||||
42
|
||||
```
|
||||
|
||||
## Accessing http request information example
|
||||
|
||||
### Setup fission environment
|
||||
First you need to setup the fission according to your cluster setup as
|
||||
specified here: https://github.com/fission/fission
|
||||
|
||||
|
||||
### Create the class to run
|
||||
|
||||
Secondly you need to create a file /tmp/func.cs containing the following code:
|
||||
|
||||
```
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
var buffer = new System.Text.StringBuilder();
|
||||
foreach(var header in context.Request.Headers){
|
||||
buffer.AppendLine(header.Key);
|
||||
foreach(var item in header.Value){
|
||||
buffer.AppendLine($"\t{item}");
|
||||
}
|
||||
}
|
||||
buffer.AppendLine($"Url: {context.Request.Url}, method: {context.Request.Method}");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
### Run the example
|
||||
|
||||
Lastly to run the example:
|
||||
|
||||
```
|
||||
$ fission env create --name dotnet --image fission/dotnet20-env
|
||||
|
||||
$ fission function create --name httpinfo --env dotnet --code /tmp/func.cs
|
||||
|
||||
$ fission route create --method GET --url /http_info --function httpinfo
|
||||
|
||||
$ curl "http://$FISSION_ROUTER/http_info"
|
||||
Accept
|
||||
*/*;q=1
|
||||
Host
|
||||
fissionserver:8888
|
||||
User-Agent
|
||||
curl/7.47.0
|
||||
Url: http://fissionserver:8888, method: GET
|
||||
|
||||
```
|
||||
|
||||
## Accessing http request body example
|
||||
|
||||
### Setup fission environment
|
||||
First you need to setup the fission according to your cluster setup as
|
||||
specified here: https://github.com/fission/fission
|
||||
|
||||
|
||||
### Create the class to run
|
||||
|
||||
Secondly you need to create a file /tmp/func.cs containing the following code:
|
||||
|
||||
```
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context)
|
||||
{
|
||||
var person = Person.Deserialize(context.Request.Body);
|
||||
return $"Hello, my name is {person.Name} and I am {person.Age} years old.";
|
||||
}
|
||||
}
|
||||
|
||||
public class Person
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Age { get; set; }
|
||||
|
||||
public static Person Deserialize(Stream json)
|
||||
{
|
||||
var serializer = new DataContractJsonSerializer(typeof(Person));
|
||||
return (Person)serializer.ReadObject(json);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
### Run the example
|
||||
|
||||
Lastly to run the example:
|
||||
|
||||
```
|
||||
$ fission env create --name dotnet --image fission/dotnet20-env
|
||||
|
||||
$ fission function create --name httpbody --env dotnet --code /tmp/func.cs
|
||||
|
||||
$ fission route create --method GET --url /http_body --function httpbody
|
||||
|
||||
$ curl -XPOST "http://$FISSION_ROUTER/http_body" -d '{ "Name":"Arthur", "Age":42}'
|
||||
Hello, my name is Arthur and I am 42 years old.
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Developing/debugging the enviroment locally
|
||||
|
||||
The easiest way to debug the environment is to open the directory in
|
||||
Visual Studio Code (VSCode) as that will setup debugger for you the
|
||||
first time.
|
||||
|
||||
Remember to install the excellent extension
|
||||
"C# for Visual Studio Code(powered by OmniSharp)" to get statement completion
|
||||
|
||||
The class ExecutorModule contain preprocessor directive overriding where
|
||||
the input code file should be found:
|
||||
|
||||
```
|
||||
#if DEBUG
|
||||
private const string CODE_PATH = "/tmp/func.cs";
|
||||
#else
|
||||
private const string CODE_PATH = "/userfunc/user";
|
||||
#endif
|
||||
```
|
||||
|
||||
So what you need to do is:
|
||||
1. Open the directory in VSCode.
|
||||
This will prompt restore of packages and query is debugger setup is needed. Accept both prompts.
|
||||
2. Press F5 to start the web server. Set breakpoints etc..
|
||||
3. Add a code file containing valid C# at /tmp/func.cs
|
||||
4. Specialize the service with curl via post
|
||||
```
|
||||
$ curl -XPOST http://localhost:8888/specialize
|
||||
```
|
||||
5. Call your function with curl
|
||||
```
|
||||
$ curl -XGET http://localhost:8888
|
||||
```
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
THIS_DIR=$(realpath $(dirname $0))
|
||||
|
||||
docker run -v $THIS_DIR:/proj microsoft/dotnet:2.0.0-sdk sh -c "cd /proj && ./project-build.sh"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.12
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "fission-dotnet20", "dotnet20\fission-dotnet20.csproj", "{3F044DE1-74E5-48F7-8D23-233C24AAA45C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3F044DE1-74E5-48F7-8D23-233C24AAA45C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3F044DE1-74E5-48F7-8D23-233C24AAA45C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3F044DE1-74E5-48F7-8D23-233C24AAA45C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3F044DE1-74E5-48F7-8D23-233C24AAA45C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {272000F7-BBEC-4B61-8865-783EF7E5CEE9}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Owin" Version="2.0.0" />
|
||||
<PackageReference Include="Nancy" Version="2.0.0-clinteastwood" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.3.2" />
|
||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||
<PackageReference Include="System.Runtime.Serialization.Json" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
dotnet restore fission-dotnet20.csproj
|
||||
dotnet publish fission-dotnet20.csproj -c Release -o out
|
||||
@@ -3,6 +3,7 @@ package client
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
//"time"
|
||||
|
||||
@@ -11,7 +12,19 @@ import (
|
||||
//"github.com/fission/fission/router"
|
||||
)
|
||||
|
||||
func DoFetchRequest(fetcherUrl string, fr *fetcher.FetchRequest) error {
|
||||
type (
|
||||
Client struct {
|
||||
url string
|
||||
}
|
||||
)
|
||||
|
||||
func MakeClient(fetcherUrl string) *Client {
|
||||
return &Client{
|
||||
url: fetcherUrl,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) Fetch(fr *fetcher.FetchRequest) error {
|
||||
body, err := json.Marshal(fr)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -21,7 +34,7 @@ func DoFetchRequest(fetcherUrl string, fr *fetcher.FetchRequest) error {
|
||||
// Transport: router.MakeRetryingRoundTripper(10, 50*time.Millisecond),
|
||||
// }
|
||||
|
||||
resp, err := http.Post(fetcherUrl, "application/json", bytes.NewReader(body))
|
||||
resp, err := http.Post(c.url, "application/json", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -33,3 +46,32 @@ func DoFetchRequest(fetcherUrl string, fr *fetcher.FetchRequest) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) Upload(fr *fetcher.UploadRequest) (*fetcher.UploadResponse, error) {
|
||||
body, err := json.Marshal(fr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := http.Post(c.url+"/upload", "application/json", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fission.MakeErrorFromHTTP(resp)
|
||||
}
|
||||
|
||||
rBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
uploadResp := fetcher.UploadResponse{}
|
||||
err = json.Unmarshal([]byte(rBody), &uploadResp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &uploadResp, nil
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ func main() {
|
||||
}
|
||||
fetcher := fetcher.MakeFetcher(dir)
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", fetcher.Handler)
|
||||
mux.HandleFunc("/", fetcher.FetchHandler)
|
||||
mux.HandleFunc("/upload", fetcher.UploadHandler)
|
||||
http.ListenAndServe(":8000", mux)
|
||||
}
|
||||
|
||||
+141
-37
@@ -16,28 +16,41 @@ import (
|
||||
|
||||
"github.com/mholt/archiver"
|
||||
"github.com/satori/go.uuid"
|
||||
"k8s.io/client-go/1.5/kubernetes"
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
storageSvcClient "github.com/fission/fission/storagesvc/client"
|
||||
)
|
||||
|
||||
type (
|
||||
FetchRequestType int
|
||||
|
||||
FetchRequest struct {
|
||||
FetchType FetchRequestType `json:"fetchType"`
|
||||
Function api.ObjectMeta `json:"function"`
|
||||
Url string `json:"url"`
|
||||
StorageSvcUrl string `json:"storagesvcurl"`
|
||||
Filename string `json:"filename"`
|
||||
FetchType FetchRequestType `json:"fetchType"`
|
||||
Package metav1.ObjectMeta `json:"package"`
|
||||
Url string `json:"url"`
|
||||
StorageSvcUrl string `json:"storagesvcurl"`
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
|
||||
// UploadRequest send from builder manager describes which
|
||||
// deployment package should be upload to storage service.
|
||||
UploadRequest struct {
|
||||
Filename string `json:"filename"`
|
||||
StorageSvcUrl string `json:"storagesvcurl"`
|
||||
}
|
||||
|
||||
// UploadResponse defines the download url of an archive and
|
||||
// its checksum.
|
||||
UploadResponse struct {
|
||||
ArchiveDownloadUrl string `json:"archiveDownloadUrl"`
|
||||
Checksum fission.Checksum `json:"checksum"`
|
||||
}
|
||||
|
||||
Fetcher struct {
|
||||
sharedVolumePath string
|
||||
fissionClient *tpr.FissionClient
|
||||
kubeClient *kubernetes.Clientset
|
||||
fissionClient *crd.FissionClient
|
||||
}
|
||||
)
|
||||
|
||||
@@ -48,14 +61,13 @@ const (
|
||||
)
|
||||
|
||||
func MakeFetcher(sharedVolumePath string) *Fetcher {
|
||||
fissionClient, kubeClient, err := tpr.MakeFissionClient()
|
||||
fissionClient, _, _, err := crd.MakeFissionClient()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &Fetcher{
|
||||
sharedVolumePath: sharedVolumePath,
|
||||
fissionClient: fissionClient,
|
||||
kubeClient: kubeClient,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,33 +91,44 @@ func downloadUrl(url string, localPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func verifyChecksum(path string, checksum *fission.Checksum) error {
|
||||
if checksum.Type != fission.ChecksumTypeSHA256 {
|
||||
return fission.MakeError(fission.ErrorInvalidArgument, "Unsupported checksum type")
|
||||
}
|
||||
|
||||
func getChecksum(path string) (*fission.Checksum, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
hasher := sha256.New()
|
||||
_, err = io.Copy(hasher, f)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := hex.EncodeToString(hasher.Sum(nil))
|
||||
if c != checksum.Sum {
|
||||
|
||||
return &fission.Checksum{
|
||||
Type: fission.ChecksumTypeSHA256,
|
||||
Sum: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func verifyChecksum(path string, checksum *fission.Checksum) error {
|
||||
if checksum.Type != fission.ChecksumTypeSHA256 {
|
||||
return fission.MakeError(fission.ErrorInvalidArgument, "Unsupported checksum type")
|
||||
}
|
||||
c, err := getChecksum(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c.Sum != checksum.Sum {
|
||||
return fission.MakeError(fission.ErrorChecksumFail, "Checksum validation failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fetcher *Fetcher) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
func (fetcher *Fetcher) FetchHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "", 405)
|
||||
http.Error(w, "only POST is supported on this endpoint", 405)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -129,7 +152,7 @@ func (fetcher *Fetcher) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), 400)
|
||||
return
|
||||
}
|
||||
log.Printf("fetcher received request: %v", req)
|
||||
log.Printf("fetcher received fetch request and started downloading: %v", req)
|
||||
|
||||
tmpFile := req.Filename + ".tmp"
|
||||
tmpPath := filepath.Join(fetcher.sharedVolumePath, tmpFile)
|
||||
@@ -144,19 +167,8 @@ func (fetcher *Fetcher) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// get function object
|
||||
fn, err := fetcher.fissionClient.Functions(req.Function.Namespace).Get(req.Function.Name)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Failed to get function: %v", err)
|
||||
log.Printf(e)
|
||||
http.Error(w, e, 500)
|
||||
return
|
||||
}
|
||||
|
||||
// get pkg
|
||||
var pkg *tpr.Package
|
||||
pkg, err = fetcher.fissionClient.
|
||||
Packages(fn.Spec.Package.PackageRef.Namespace).Get(fn.Spec.Package.PackageRef.Name)
|
||||
pkg, err := fetcher.fissionClient.Packages(req.Package.Namespace).Get(req.Package.Name)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Failed to get package: %v", err)
|
||||
log.Printf(e)
|
||||
@@ -200,7 +212,6 @@ func (fetcher *Fetcher) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check file type here, if the file is a zip file unarchive it.
|
||||
@@ -229,6 +240,85 @@ func (fetcher *Fetcher) Handler(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (fetcher *Fetcher) UploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "only POST is supported on this endpoint", 405)
|
||||
return
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
defer func() {
|
||||
elapsed := time.Now().Sub(startTime)
|
||||
log.Printf("elapsed time in upload request = %v", elapsed)
|
||||
}()
|
||||
|
||||
// parse request
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
log.Printf("Error reading request body")
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
}
|
||||
|
||||
var req UploadRequest
|
||||
err = json.Unmarshal(body, &req)
|
||||
if err != nil {
|
||||
log.Printf("Error reading request body: %v", err)
|
||||
http.Error(w, err.Error(), 400)
|
||||
return
|
||||
}
|
||||
log.Printf("fetcher received upload request: %v", req)
|
||||
|
||||
zipFilename := req.Filename + ".zip"
|
||||
srcFilepath := filepath.Join(fetcher.sharedVolumePath, req.Filename)
|
||||
dstFilepath := filepath.Join(fetcher.sharedVolumePath, zipFilename)
|
||||
|
||||
err = fetcher.archive(srcFilepath, dstFilepath)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error archiving zip file: %v", err)
|
||||
log.Println(e)
|
||||
http.Error(w, e, 500)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("Starting upload...")
|
||||
ssClient := storageSvcClient.MakeClient(req.StorageSvcUrl)
|
||||
|
||||
fileID, err := ssClient.Upload(dstFilepath, nil)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error uploading zip file: %v", err)
|
||||
log.Println(e)
|
||||
http.Error(w, e, 500)
|
||||
return
|
||||
}
|
||||
|
||||
sum, err := getChecksum(dstFilepath)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error calculating checksum of zip file: %v", err)
|
||||
log.Println(e)
|
||||
http.Error(w, e, 500)
|
||||
return
|
||||
}
|
||||
|
||||
resp := UploadResponse{
|
||||
ArchiveDownloadUrl: ssClient.GetUrl(fileID),
|
||||
Checksum: *sum,
|
||||
}
|
||||
|
||||
rBody, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("Error encoding upload response: %v", err)
|
||||
log.Println(e)
|
||||
http.Error(w, e, 500)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("Completed upload request")
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.Write(rBody)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (fetcher *Fetcher) rename(src string, dst string) error {
|
||||
err := os.Rename(src, dst)
|
||||
if err != nil {
|
||||
@@ -239,7 +329,21 @@ func (fetcher *Fetcher) rename(src string, dst string) error {
|
||||
|
||||
// archive is a function that zips directory into a zip file
|
||||
func (fetcher *Fetcher) archive(src string, dst string) error {
|
||||
return archiver.Zip.Make(dst, []string{src})
|
||||
var files []string
|
||||
target, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Failed to zip file: %v", err))
|
||||
}
|
||||
if target.IsDir() {
|
||||
// list all
|
||||
fs, _ := ioutil.ReadDir(src)
|
||||
for _, f := range fs {
|
||||
files = append(files, filepath.Join(src, f.Name()))
|
||||
}
|
||||
} else {
|
||||
files = append(files, src)
|
||||
}
|
||||
return archiver.Zip.Make(dst, files)
|
||||
}
|
||||
|
||||
// unarchive is a function that unzips a zip file to destination
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
# A docker image for the func container.
|
||||
|
||||
FROM node:7-onbuild
|
||||
# default variant is the official alpine node image (much smaller than the standard image)
|
||||
FROM node:8-alpine
|
||||
|
||||
ADD server.js /usr/src/app/server.js
|
||||
ARG NODE_ENV
|
||||
ENV NODE_ENV $NODE_ENV
|
||||
|
||||
EXPOSE 8888
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY package.json /usr/src/app/
|
||||
RUN npm install && npm cache clean --force
|
||||
COPY server.js /usr/src/app/server.js
|
||||
|
||||
CMD [ "npm", "start" ]
|
||||
|
||||
EXPOSE 8888
|
||||
@@ -0,0 +1,18 @@
|
||||
# A docker image for the func container.
|
||||
|
||||
# debian variant is the official standard node image (larger than the alpine image)
|
||||
FROM node:8
|
||||
|
||||
ARG NODE_ENV
|
||||
ENV NODE_ENV $NODE_ENV
|
||||
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY package.json /usr/src/app/
|
||||
RUN npm install && npm cache clean --force
|
||||
COPY server.js /usr/src/app/server.js
|
||||
|
||||
CMD [ "npm", "start" ]
|
||||
|
||||
EXPOSE 8888
|
||||
@@ -13,12 +13,12 @@
|
||||
"node": ">=7.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"body-parser": "",
|
||||
"body-parser": "*",
|
||||
"co": "~4.6.0",
|
||||
"express": "",
|
||||
"minimist": "",
|
||||
"morgan": "",
|
||||
"mz": "~2.1.0",
|
||||
"express": "*",
|
||||
"minimist": "*",
|
||||
"morgan": "*",
|
||||
"mz": "~2.7.0",
|
||||
"request": "^2.81.0",
|
||||
"request-promise-native": "^1.0.3",
|
||||
"underscore": ">=1.8.3"
|
||||
|
||||
@@ -66,6 +66,7 @@ app.use(morgan('combined'))
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.raw());
|
||||
app.use(bodyParser.text({ type : "text/*" }));
|
||||
|
||||
app.post('/specialize', specialize);
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@ RUN pip3 install --upgrade pip
|
||||
RUN rm -r /root/.cache
|
||||
|
||||
ADD defaultBuildCmd /usr/local/bin/build
|
||||
ADD builder /
|
||||
ADD builder /builder
|
||||
|
||||
EXPOSE 8000
|
||||
EXPOSE 8001
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
builderDir=${GOPATH}/src/github.com/fission/fission/builder/cmd
|
||||
pushd ${builderDir}
|
||||
GOOS=linux GOARCH=386 go build -o builder .
|
||||
popd
|
||||
cp ${builderDir}/builder .
|
||||
docker build -t python-builder .
|
||||
docker tag python-builder fission/python-builder:$tag
|
||||
docker push fission/python-builder:$tag
|
||||
|
||||
@@ -3,21 +3,64 @@
|
||||
import logging
|
||||
import sys
|
||||
import imp
|
||||
import os
|
||||
|
||||
from flask import Flask, request, abort, g
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
codepath = '/userfunc/user'
|
||||
|
||||
userfunc = None
|
||||
|
||||
@app.route('/specialize', methods=['POST'])
|
||||
def load():
|
||||
global userfunc
|
||||
# load user function from codepath
|
||||
codepath = '/userfunc/user'
|
||||
userfunc = (imp.load_source('user', codepath)).main
|
||||
return ""
|
||||
|
||||
@app.route('/v2/specialize', methods=['POST'])
|
||||
def loadv2():
|
||||
global userfunc
|
||||
body = request.get_json()
|
||||
filepath = body['filepath']
|
||||
handler = body['functionName']
|
||||
|
||||
# The value of "functionName" is consist of `<module-name>.<function-name>`.
|
||||
moduleName, funcName = handler.split(".")
|
||||
|
||||
# check whether the destination is a directory or a file
|
||||
if os.path.isdir(filepath):
|
||||
# add package directory path into module search path
|
||||
sys.path.append(filepath)
|
||||
|
||||
# find module from package path we append previously.
|
||||
# Python will try to find module from the same name file under
|
||||
# the package directory. If search is successful, the return
|
||||
# value is a 3-element tuple; otherwise, an exception "ImportError"
|
||||
# is raised.
|
||||
# Second parameter of find_module enforces python to find same
|
||||
# name module from the given list of directories to prevent name
|
||||
# confliction with built-in modules.
|
||||
f, path, desc = imp.find_module(moduleName, [filepath])
|
||||
|
||||
# load module
|
||||
# Return module object is the load is successful; otherwise,
|
||||
# an exception is raised.
|
||||
try:
|
||||
mod = imp.load_module(moduleName, f, path, desc)
|
||||
finally:
|
||||
if f:
|
||||
f.close()
|
||||
else:
|
||||
# load source from destination python file
|
||||
mod = imp.load_source(moduleName, filepath)
|
||||
|
||||
# load user function from module
|
||||
userfunc = getattr(mod, funcName)
|
||||
|
||||
return ""
|
||||
|
||||
@app.route('/', methods=['GET', 'POST', 'PUT', 'HEAD', 'OPTIONS', 'DELETE'])
|
||||
def f():
|
||||
if userfunc == None:
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
var x = Convert.ToInt32(context.Arguments["x"]);
|
||||
var y = Convert.ToInt32(context.Arguments["y"]);
|
||||
return (x+y).ToString();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
context.Logger.WriteInfo("executing.. {0}", context.Arguments["text"]);
|
||||
return (string)context.Arguments["text"];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context)
|
||||
{
|
||||
return "Hello World!";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context)
|
||||
{
|
||||
var person = Person.Deserialize(context.Request.Body);
|
||||
return $"Hello, my name is {person.Name} and I am {person.Age} years old.";
|
||||
}
|
||||
}
|
||||
|
||||
public class Person
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Age { get; set; }
|
||||
|
||||
public static Person Deserialize(Stream json)
|
||||
{
|
||||
var serializer = new DataContractJsonSerializer(typeof(Person));
|
||||
return (Person)serializer.ReadObject(json);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
var buffer = new System.Text.StringBuilder();
|
||||
foreach(var header in context.Request.Headers){
|
||||
buffer.AppendLine(header.Key);
|
||||
foreach(var item in header.Value){
|
||||
buffer.AppendLine($"\t{item}");
|
||||
}
|
||||
}
|
||||
buffer.AppendLine($"Url: {context.Request.Url}, method: {context.Request.Method}");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,19 @@
|
||||
|
||||
This directory contains several examples to get you started using Node.js with Fission.
|
||||
|
||||
## Environment
|
||||
|
||||
Before running any of these functions, make sure you have created a `nodejs` Fission environment:
|
||||
|
||||
```
|
||||
$ fission env create --name nodejs --image fission/node-env
|
||||
```
|
||||
|
||||
Note: The default `fission/node-env` image is based on Alpine, which is much smaller than the main Debian Node image (65MB vs 680MB) while still being suitable for most use cases.
|
||||
If you need to use the full Debian image use the `fission/node-env-debian` image instead.
|
||||
See the [official Node docker hub repo](https://hub.docker.com/_/node/) for considerations
|
||||
relating to this choice.
|
||||
|
||||
## Function signature
|
||||
|
||||
Every Node.js function has the same basic form:
|
||||
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
pip3 install -r ${SRC_PKG}/requirements.txt -t ${SRC_PKG} && cp -r ${SRC_PKG} ${DEPLOY_PKG}
|
||||
@@ -0,0 +1 @@
|
||||
pyyaml
|
||||
@@ -0,0 +1,12 @@
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
document = """
|
||||
a: 1
|
||||
b:
|
||||
c: 3
|
||||
d: 4
|
||||
"""
|
||||
|
||||
def main():
|
||||
return yaml.dump(yaml.load(document))
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/bin/sh
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
|
||||
|
||||
+31
-13
@@ -6,6 +6,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/docopt/docopt-go"
|
||||
"github.com/fission/fission/buildermgr"
|
||||
"github.com/fission/fission/controller"
|
||||
"github.com/fission/fission/kubewatcher"
|
||||
"github.com/fission/fission/logger"
|
||||
@@ -68,6 +69,13 @@ func runStorageSvc(port int, filePath string) {
|
||||
filePath, subdir, port)
|
||||
}
|
||||
|
||||
func runBuilderMgr(port int, storageSvcUrl string, envBuilderNamespace string) {
|
||||
err := buildermgr.Start(port, storageSvcUrl, envBuilderNamespace)
|
||||
if err != nil {
|
||||
log.Fatalf("Error starting buildermgr: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func getPort(portArg interface{}) int {
|
||||
portArgStr := portArg.(string)
|
||||
port, err := strconv.Atoi(portArgStr)
|
||||
@@ -113,23 +121,26 @@ Usage:
|
||||
fission-bundle --poolmgrPort=<port> [--namespace=<namespace>] [--fission-namespace=<namespace>]
|
||||
fission-bundle --kubewatcher [--routerUrl=<url>]
|
||||
fission-bundle --storageServicePort=<port> --filePath=<filePath>
|
||||
fission-bundle --builderMgrPort=<port> [--storageSvcUrl=<url>] [--envbuilder-namespace=<namespace>]
|
||||
fission-bundle --logger
|
||||
fission-bundle --timer [--routerUrl=<url>]
|
||||
fission-bundle --mqt [--routerUrl=<url>]
|
||||
Options:
|
||||
--controllerPort=<port> Port that the controller should listen on.
|
||||
--routerPort=<port> Port that the router should listen on.
|
||||
--poolmgrPort=<port> Port that the poolmgr should listen on.
|
||||
--storageServicePort=<port> Port that the storage service should listen on.
|
||||
--poolmgrUrl=<url> Poolmgr URL. Not required if --poolmgrPort is specified.
|
||||
--routerUrl=<url> Router URL.
|
||||
--etcdUrl=<etcdUrl> Etcd URL.
|
||||
--filePath=<filePath> Directory to store functions in.
|
||||
--namespace=<namespace> Kubernetes namespace in which to run function containers. Defaults to 'fission-function'.
|
||||
--kubewatcher Start Kubernetes events watcher.
|
||||
--logger Start logger.
|
||||
--timer Start Timer.
|
||||
--mqt Start message queue trigger.
|
||||
--controllerPort=<port> Port that the controller should listen on.
|
||||
--routerPort=<port> Port that the router should listen on.
|
||||
--poolmgrPort=<port> Port that the poolmgr should listen on.
|
||||
--storageServicePort=<port> Port that the storage service should listen on.
|
||||
--builderMgrPort=<port> Port that the buildermgr should listen on.
|
||||
--poolmgrUrl=<url> Poolmgr URL. Not required if --poolmgrPort is specified.
|
||||
--routerUrl=<url> Router URL.
|
||||
--etcdUrl=<etcdUrl> Etcd URL.
|
||||
--storageSvcUrl=<url> StorageService URL.
|
||||
--filePath=<filePath> Directory to store functions in.
|
||||
--namespace=<namespace> Kubernetes namespace in which to run function containers. Defaults to 'fission-function'.
|
||||
--kubewatcher Start Kubernetes events watcher.
|
||||
--logger Start logger.
|
||||
--timer Start Timer.
|
||||
--mqt Start message queue trigger.
|
||||
`
|
||||
arguments, err := docopt.Parse(usage, nil, true, "fission-bundle", false)
|
||||
if err != nil {
|
||||
@@ -138,9 +149,11 @@ Options:
|
||||
|
||||
functionNs := getStringArgWithDefault(arguments["--namespace"], "fission-function")
|
||||
fissionNs := getStringArgWithDefault(arguments["--fission-namespace"], "fission")
|
||||
envBuilderNs := getStringArgWithDefault(arguments["--envbuilder-namespace"], "fission-builder")
|
||||
|
||||
poolmgrUrl := getStringArgWithDefault(arguments["--poolmgrUrl"], "http://poolmgr.fission")
|
||||
routerUrl := getStringArgWithDefault(arguments["--routerUrl"], "http://router.fission")
|
||||
storageSvcUrl := getStringArgWithDefault(arguments["--storageSvcUrl"], "http://storagesvc.fission")
|
||||
|
||||
if arguments["--controllerPort"] != nil {
|
||||
port := getPort(arguments["--controllerPort"])
|
||||
@@ -179,5 +192,10 @@ Options:
|
||||
runStorageSvc(port, filePath)
|
||||
}
|
||||
|
||||
if arguments["--builderMgrPort"] != nil {
|
||||
port := getPort(arguments["--builderMgrPort"])
|
||||
runBuilderMgr(port, storageSvcUrl, envBuilderNs)
|
||||
}
|
||||
|
||||
select {}
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: router
|
||||
namespace: fission
|
||||
labels:
|
||||
svc: router
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8888
|
||||
nodePort: 31314
|
||||
selector:
|
||||
svc: router
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: controller
|
||||
namespace: fission
|
||||
labels:
|
||||
svc: controller
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8888
|
||||
nodePort: 31313
|
||||
selector:
|
||||
svc: controller
|
||||
|
||||
---
|
||||
# If you want to switch to external db service, please checkout
|
||||
# sample Kubernetes Service config in fission-logger.yaml.
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: influxdb
|
||||
namespace: fission
|
||||
labels:
|
||||
svc: influxdb
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 8086
|
||||
targetPort: 8086
|
||||
nodePort: 31315
|
||||
selector:
|
||||
svc: influxdb
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nats-streaming
|
||||
namespace: fission
|
||||
labels:
|
||||
svc: nats-streaming
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 4222
|
||||
targetPort: 4222
|
||||
nodePort: 31316
|
||||
selector:
|
||||
svc: nats-streaming
|
||||
@@ -1,122 +0,0 @@
|
||||
# Sample Kubernetes Service config for external db service.
|
||||
#
|
||||
# apiVersion: v1
|
||||
# kind: Service
|
||||
# metadata:
|
||||
# name: influxdb
|
||||
# namespace: fission
|
||||
# spec:
|
||||
# ports:
|
||||
# - name: "8086"
|
||||
# port: 8086
|
||||
# targetPort: 8086
|
||||
# protocol: TCP
|
||||
|
||||
# ---
|
||||
# apiVersion: v1
|
||||
# kind: Endpoints
|
||||
# metadata:
|
||||
# name: influxdb
|
||||
# namespace: fission
|
||||
# subsets:
|
||||
# - addresses:
|
||||
# - ip: replace.influxdb.host.here
|
||||
# ports:
|
||||
# - name: "8086"
|
||||
# port: 8086
|
||||
# protocol: TCP
|
||||
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: influxdb
|
||||
namespace: fission
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
svc: influxdb
|
||||
spec:
|
||||
containers:
|
||||
- name: influxdb
|
||||
image: tutum/influxdb
|
||||
env:
|
||||
- name: PRE_CREATE_DB
|
||||
value: fissionFunctionLog
|
||||
# Create a random username/password for InfluxDB here, and
|
||||
# repeat it in the fluentd spec below.
|
||||
- name: ADMIN_USER
|
||||
value: ""
|
||||
- name: INFLUXDB_INIT_PWD
|
||||
value: ""
|
||||
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: logger
|
||||
namespace: fission
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
svc: logger
|
||||
spec:
|
||||
containers:
|
||||
- name: logger
|
||||
image: fission/fission-bundle
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["/fission-bundle"]
|
||||
args: ["--logger"]
|
||||
volumeMounts:
|
||||
- name: container-log
|
||||
mountPath: /var/log/containers
|
||||
readOnly: true
|
||||
- name: docker-log
|
||||
mountPath: /var/lib/docker/containers
|
||||
readOnly: true
|
||||
- name: fission-log
|
||||
mountPath: /var/log/fission
|
||||
readOnly: false
|
||||
ports:
|
||||
- containerPort: 1234
|
||||
hostPort: 1234
|
||||
protocol: TCP
|
||||
- name: fluentd
|
||||
image: fission/fluentd
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: INFLUXDB_ADDRESS
|
||||
value: influxdb
|
||||
- name: INFLUXDB_PORT
|
||||
value: "8086"
|
||||
- name: INFLUXDB_DBNAME
|
||||
value: "fissionFunctionLog"
|
||||
# Username/password for fluentd to push logs to
|
||||
# influxdb. This should match the influxdb
|
||||
# username/passowrd defined above.
|
||||
- name: INFLUXDB_USERNAME
|
||||
value: ""
|
||||
- name: INFLUXDB_PASSWD
|
||||
value: ""
|
||||
volumeMounts:
|
||||
- name: container-log
|
||||
mountPath: /var/log/containers
|
||||
readOnly: true
|
||||
- name: docker-log
|
||||
mountPath: /var/lib/docker/containers
|
||||
readOnly: true
|
||||
- name: fission-log
|
||||
mountPath: /var/log/fission
|
||||
readOnly: false
|
||||
volumes:
|
||||
- name: container-log
|
||||
hostPath:
|
||||
path: /var/log/containers
|
||||
- name: docker-log
|
||||
hostPath:
|
||||
path: /var/lib/docker/containers
|
||||
- name: fission-log
|
||||
hostPath:
|
||||
path: /var/log/fission
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user