Compare commits

..
28 Commits
Author SHA1 Message Date
Soam Vasani 8a097abf9b Chart version update 2017-11-15 13:25:28 -08:00
Soam Vasani 6d0ebfd881 update version to 0.4.0 in docs 2017-11-15 13:18:50 -08:00
Soam Vasani 310183a944 update version to 0.4.0 2017-11-15 13:18:22 -08:00
Soam Vasani 8fc3479428 only set nodeports when servicetype == nodeport 2017-11-15 13:18:22 -08:00
Josh KellyandSoam Vasani b2883a30de Added AWS to install cloud setup (#392)
Add AWS instructions to setup commands, since AWS only provides service hostname, not IP.
2017-11-15 12:49:19 -08:00
prithvirameshandSoam Vasani 8b40ad0b33 Refactor logging to remove logger, use fluentd with kubernetes filter (#380)
Remove the `logger` container from the logging daemonset. 

Remove the outgoing call from the poolmgr to the logger.  Use Fluentd's Kubernetes filter to add function name and UID to influx metadata.  

This means fluentd now figures out when to start collecting function logs on its own, without being informed by poolmgr.  This is great for other execution strategies, and for autoscaling, where fission isn't in direct control of function pod creation.

Also adds an integration test to make sure logging keeps working.
2017-11-14 18:08:57 -08:00
svicenteruizandSoam Vasani 74e05ba3a1 created weather.js in node.js examples, modified README.md (#394) 2017-11-14 15:33:41 -08:00
Cody HillandSoam Vasani e77a3946d7 Added python example to demonstrate status codes. (#395) 2017-11-14 05:51:37 -08:00
Soam Vasani bcf04b1a6c Build both python 3.5 and 2.7 images from the same env 2017-11-09 14:01:02 -08:00
Soam Vasani d8844ab13c release script: use helm package to create charts 2017-11-09 13:38:01 -08:00
Soam Vasani 2e63787b96 rename readme to format markdown 2017-11-09 08:12:47 -08:00
Soam Vasani de19a42b8b multifile example 2017-11-09 08:11:02 -08:00
Ta-Ching ChenandSoam Vasani da07b35a96 Use common controller/store for httpTriggerSet and functionReferenceResolver (#390)
This fixes a bug where functionReferenceResolver returned out-of-date function metadata and caused the router to proxy requests to old function pods.

It also uses the go context package to shutdown the controller when the router is shutting down.
2017-11-09 07:07:14 -08:00
Ta-Ching ChenandSoam Vasani 9694ba4fd1 Delete failed helm releases to prevent test case failure (#393) 2017-11-09 06:04:06 -08:00
Soam Vasani 3644760f19 hugo config 2017-11-08 17:15:54 -08:00
Soam Vasani b89576ff7d chart version update 2017-11-08 15:51:23 -08:00
Soam Vasani d4b4385596 0.4.0rc version update 2017-11-08 12:45:09 -08:00
Soam Vasani b8eb27d276 Upgrade guide doc update 2017-11-07 15:45:39 -08:00
Ta-Ching ChenandSoam Vasani a63b8b372f Builder manager bugfixes (#367)
This contains a few different builder manager fixes:

* Update the zip file structure to avoid an extra subdirectory
* Annotate packages with what functions are using them
* Only trigger builds when there is no deployment archive
* Python environment loadpath bugfixes
* Other bugfixes
2017-11-06 23:01:46 -08:00
Ta-Ching ChenandSoam Vasani 380b7d1bcd Use k8s client store to sync functions and triggers for fast synchronization (#382) 2017-11-06 12:58:19 -08:00
Ta-Ching ChenandSoam Vasani 5f14b9b0ae Switch from ThirdPartyResources to CustomResourceDefinitions (#381)
Switch Fission's storage over to the new CustomResourceDefinitions, from the deprecated ThirdPartyResources. This allows us to be compatible with Kubernets 1.8 and onwards.

This also adds a CLI tool for dumping state from an old fission version and restoring state into new CRDs.

The storage service is unaffected by this change.
2017-11-04 14:55:16 -07:00
VishalandSoam Vasani 746c51901d Test functions 236 (#355)
A single CLI command to invoke a function, print results, and get logs if the function fails. Meant to be an easy way to do testing from the CLI.
2017-10-30 22:32:15 -07:00
Ta-Ching ChenandSoam Vasani 439e7d4535 Use Kubernetes informer and cache in router (#376)
Use Kubernetes client's informer and cache to watch functions and triggers in the router. This replaces the polling loop we were using so far.
2017-10-25 15:10:44 -07:00
prithvirameshandSoam Vasani 8abb0005f6 Compile instructions: changed pullPolicy to IfNotPresent (#378)
Containers will get stuck in ErrImagePull/ImagePullBackOff state otherwise
2017-10-16 13:39:46 -07:00
Soam Vasani c8f4647373 update compiling.md to use helm 2017-10-05 16:24:25 -07:00
rapitableandSoam Vasani 5c47073518 Make default node-env use alpine. List envs in documentation. (#354)
closes #319 

* Make default node-env use alpine, and support separate debian env. List envs in documentation.

* Copy ONBUILD base image commands into node Dockerfiles

* Copy more commands from onbuild image

* Tidy dockerfiles
2017-10-04 19:05:43 -07:00
Soam Vasani fd1461cc98 doc formatting fixes 2017-10-02 14:54:40 -07:00
Ta-Ching ChenandSoam Vasani a25c167d23 Update k8s client version to 4.0.0 (#351)
Move to client-go v4.0.0 from 1.5.
2017-09-29 07:37:36 -07:00
131 changed files with 3119 additions and 2219 deletions
+2 -5
View File
@@ -38,13 +38,10 @@ minikube and its built-in docker daemon:
$ docker build -t minikube/fission-bundle . $ 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" $ helm install --set "image=minikube/fission-bundle,pullPolicy=IfNotPresent,analytics=false" charts/fission-all
$ $EDITOR fission.yaml
$ kubectl create -f fission.yaml
$ kubectl create -f fission-nodeport.yaml
``` ```
And if you're changing the CLI too, you can build it with: And if you're changing the CLI too, you can build it with:
+5 -5
View File
@@ -24,7 +24,7 @@ Language-neutral components:
Language-specific components: Language-specific components:
* Environment container * Environment container(s)
Controller Controller
@@ -112,13 +112,13 @@ Environment Container
--------------------- ---------------------
Environment containers run user-defined functions. Environment Environment containers run user-defined functions. Environment
containers are language specific. They must contain an HTTP server containers are language specific. Each environment container must
and a loader for functions. contain an HTTP server and a loader for functions.
Poolmgr deploys the environment container into a pod with fetcher 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 (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 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 When poolmgr needs to create a service for a function, it calls
fetcher to fetch the function. Fetcher downloads the function into a fetcher to fetch the function. Fetcher downloads the function into a
@@ -134,7 +134,7 @@ Following is a diagram describe how log service works:
![Logger Diagram](https://cloud.githubusercontent.com/assets/202578/23100399/b0e3ea00-f6ba-11e6-8f2f-6588cfef2e84.png) ![Logger Diagram](https://cloud.githubusercontent.com/assets/202578/23100399/b0e3ea00-f6ba-11e6-8f2f-6588cfef2e84.png)
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 2. Pool manager makes a HTTP POST to logger helper, once helper receives
the request it creates a symlink to container log for fluentd. the request it creates a symlink to container log for fluentd.
3. Fluentd reads log from symlink and pipes to influxdb 3. Fluentd reads log from symlink and pipes to influxdb
+1 -1
View File
@@ -10,7 +10,7 @@
## Fission API ([area-api](https://github.com/fission/fission/labels/area-api)) ## Fission API ([area-api](https://github.com/fission/fission/labels/area-api))
- TPR-based controller - CRD-based controller
- API authentication - API authentication
- Aggregated API server - Aggregated API server
+2 -1
View File
@@ -1,3 +1,4 @@
baseURL = "http://fission.io/docs/v0.2.1" baseURL = "http://fission.io/docs/0.3.0"
languageCode = "en-us" languageCode = "en-us"
title = "Fission: Serverless Functions for Kubernetes" title = "Fission: Serverless Functions for Kubernetes"
theme = "docdock"
+2 -2
View File
@@ -1,6 +1,6 @@
## Fission Documentation ## Fission Documentation
* [Installation guide](install)
* [Upgrade guide for v0.3 to v0.4](upgrade-from-v0.3)
[Installation guide](install)
[Upgrade guide](upgrade-from-v0.1)
+19 -21
View File
@@ -48,18 +48,18 @@ First, you'll need the helm CLI:
On __OS X__: On __OS X__:
``` ```
$ curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.6.1-darwin-amd64.tar.gz $ curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.7.0-darwin-amd64.tar.gz
$ tar xzf helm-v2.6.1-darwin-amd64.tar.gz $ tar xzf helm-v2.7.0-darwin-amd64.tar.gz
$ mv darwin-amd64/helm /usr/local/bin $ mv darwin-amd64/helm /usr/local/bin
``` ```
On __Linux__: On __Linux__:
``` ```
$ curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.6.1-linux-amd64.tar.gz $ curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.7.0-linux-amd64.tar.gz
$ tar xzf helm-v2.6.1-linux-amd64.tar.gz $ tar xzf helm-v2.7.0-linux-amd64.tar.gz
$ mv linux-amd64/helm /usr/local/bin $ mv linux-amd64/helm /usr/local/bin
``` ```
@@ -67,24 +67,15 @@ $ mv linux-amd64/helm /usr/local/bin
Next, install the Helm server on your Kubernetes cluster: Next, install the Helm server on your Kubernetes cluster:
``` ```
$ kubectl -n kube-system create sa tiller $ helm init
$ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller
$ helm init --service-account tiller
``` ```
(The first two commands are there to make sure that helm is allowed to
install stuff on Kubernetes, in the common case that your cluster has
role-based access control.)
### Install Fission ### Install Fission
#### Minikube #### Minikube
``` ```
$ helm install --namespace fission --set serviceType=NodePort https://github.com/fission/fission/releases/download/0.3.0/fission-all-0.3.0.tgz $ helm install --namespace fission --set serviceType=NodePort https://github.com/fission/fission/releases/download/0.4.0/fission-all-0.4.0.tgz
``` ```
The serviceType variable allows configuring the type of Kubernetes The serviceType variable allows configuring the type of Kubernetes
@@ -94,7 +85,7 @@ want to expose anything outside the cluster.
#### Cloud hosted clusters (GKE, AWS, Azure etc.) #### Cloud hosted clusters (GKE, AWS, Azure etc.)
``` ```
$ helm install --namespace fission https://github.com/fission/fission/releases/download/0.3.0/fission-all-0.3.0.tgz $ helm install --namespace fission https://github.com/fission/fission/releases/download/0.4.0/fission-all-0.4.0.tgz
``` ```
#### Minimal version #### Minimal version
@@ -104,7 +95,7 @@ the NATS message queue, influxDB for logs, etc. If you want a more
minimal setup, you can install the fission-core chart instead: minimal setup, you can install the fission-core chart instead:
``` ```
$ helm install --namespace fission https://github.com/fission/fission/releases/download/0.3.0/fission-core-0.3.0.tgz $ helm install --namespace fission https://github.com/fission/fission/releases/download/0.4.0/fission-core-0.4.0.tgz
``` ```
### Install the Fission CLI ### Install the Fission CLI
@@ -114,19 +105,19 @@ $ helm install --namespace fission https://github.com/fission/fission/releases/d
Get the CLI binary for Mac: Get the CLI binary for Mac:
``` ```
$ 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/ $ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
``` ```
#### Linux #### Linux
``` ```
$ 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/ $ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
``` ```
#### Windows #### Windows
For Windows, you can use the linux binary on WSL. Or you can download 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.3.0/fission-cli-windows.exe) this windows executable: [fission.exe](https://github.com/fission/fission/releases/download/0.4.0/fission-cli-windows.exe)
### Set environment vars ### Set environment vars
@@ -149,6 +140,13 @@ FISSION_URL and FISSION_ROUTER, respectively. Wait for services to
get IP addresses (check this with ```kubectl --namespace fission get get IP addresses (check this with ```kubectl --namespace fission get
svc```). Then: svc```). Then:
##### AWS
```
$ export FISSION_URL=http://$(kubectl --namespace fission get svc controller -o=jsonpath='{..hostname}')
$ export FISSION_ROUTER=$(kubectl --namespace fission get svc router -o=jsonpath='{..hostname}')
```
##### GCP
``` ```
$ export FISSION_URL=http://$(kubectl --namespace fission get svc controller -o=jsonpath='{..ip}') $ 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}') $ export FISSION_ROUTER=$(kubectl --namespace fission get svc router -o=jsonpath='{..ip}')
@@ -159,7 +157,7 @@ svc```). Then:
Finally, you're ready to use Fission! Finally, you're ready to use Fission!
``` ```
$ fission env create --name nodejs --image fission/node-env:0.3.0 $ fission env create --name nodejs --image fission/node-env:0.4.0
$ curl -LO https://raw.githubusercontent.com/fission/fission/master/examples/nodejs/hello.js $ 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 CLI
2. Get the Fission state from v0.3 install
3. Upgrade to Fission 0.4.0
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/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/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/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
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
```
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
```
+18 -2
View File
@@ -45,8 +45,24 @@ A _function_ is a piece of code that follows the fission function
interface. interface.
An _environment_ contains the language- and runtime-specific parts of An _environment_ contains the language- and runtime-specific parts of
running a function. Fission comes with NodeJS and Python running a function.
environments; you can also extend environments or create entirely new
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 ones if you want. (An environment is essentially just a container
with a webserver and dynamic loader.) with a webserver and dynamic loader.)
+6 -6
View File
@@ -26,27 +26,27 @@ import (
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"k8s.io/client-go/1.5/kubernetes" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/api" "k8s.io/client-go/kubernetes"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
type ( type (
BuildRequest struct { BuildRequest struct {
Package api.ObjectMeta `json:"package"` Package metav1.ObjectMeta `json:"package"`
} }
BuilderMgr struct { BuilderMgr struct {
fissionClient *tpr.FissionClient fissionClient *crd.FissionClient
kubernetesClient *kubernetes.Clientset kubernetesClient *kubernetes.Clientset
storageSvcUrl string storageSvcUrl string
namespace string namespace string
} }
) )
func MakeBuilderMgr(fissionClient *tpr.FissionClient, func MakeBuilderMgr(fissionClient *crd.FissionClient,
kubernetesClient *kubernetes.Clientset, storageSvcUrl string, kubernetesClient *kubernetes.Clientset, storageSvcUrl string,
envBuilderNamespace string) *BuilderMgr { envBuilderNamespace string) *BuilderMgr {
+2 -2
View File
@@ -19,12 +19,12 @@ package buildermgr
import ( import (
"log" "log"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
// Start the buildermgr service. // Start the buildermgr service.
func Start(port int, storageSvcUrl string, envBuilderNamespace string) error { func Start(port int, storageSvcUrl string, envBuilderNamespace string) error {
fissionClient, kubernetesClient, err := tpr.MakeFissionClient() fissionClient, kubernetesClient, _, err := crd.MakeFissionClient()
if err != nil { if err != nil {
log.Printf("Failed to get kubernetes client: %v", err) log.Printf("Failed to get kubernetes client: %v", err)
return err return err
+23 -22
View File
@@ -21,16 +21,16 @@ import (
"log" "log"
"strings" "strings"
"k8s.io/client-go/1.5/kubernetes" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/api" "k8s.io/client-go/kubernetes"
"github.com/dchest/uniuri" "github.com/dchest/uniuri"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/builder" "github.com/fission/fission/builder"
builderClient "github.com/fission/fission/builder/client" builderClient "github.com/fission/fission/builder/client"
"github.com/fission/fission/crd"
"github.com/fission/fission/environments/fetcher" "github.com/fission/fission/environments/fetcher"
fetcherClient "github.com/fission/fission/environments/fetcher/client" fetcherClient "github.com/fission/fission/environments/fetcher/client"
"github.com/fission/fission/tpr"
) )
// buildPackage helps to build source package into deployment package. // buildPackage helps to build source package into deployment package.
@@ -43,13 +43,13 @@ import (
// 6. Update package status to succeed state // 6. Update package status to succeed state
// 7. Update package resource in package ref of functions that share the same package // 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 // *. Update package status to failed state,if any one of steps above failed
func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes.Clientset, func buildPackage(fissionClient *crd.FissionClient, kubernetesClient *kubernetes.Clientset,
builderNamespace string, storageSvcUrl string, buildReq BuildRequest) (buildLogs string, err error) { builderNamespace string, storageSvcUrl string, buildReq BuildRequest) (buildLogs string, err error) {
pkg, err := fissionClient.Packages( pkg, err := fissionClient.Packages(
buildReq.Package.Namespace).Get(buildReq.Package.Name) buildReq.Package.Namespace).Get(buildReq.Package.Name)
if err != nil { if err != nil {
e := fmt.Sprintf("Error getting function TPR info: %v", err) e := fmt.Sprintf("Error getting function CRD info: %v", err)
log.Println(e) log.Println(e)
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil) updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
return e, fission.MakeError(500, e) return e, fission.MakeError(500, e)
@@ -64,7 +64,14 @@ func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes
// update package status to running state, so that // update package status to running state, so that
// we can know what status a package is through cli. // we can know what status a package is through cli.
_, err = updatePackage(fissionClient, pkg, fission.BuildStatusRunning, "", nil) 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 { if err != nil {
e := fmt.Sprintf("Error setting package pending state: %v", err) e := fmt.Sprintf("Error setting package pending state: %v", err)
log.Println(e) log.Println(e)
@@ -72,9 +79,9 @@ func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes
return e, fission.MakeError(500, e) return e, fission.MakeError(500, e)
} }
env, err := fissionClient.Environments(api.NamespaceDefault).Get(pkg.Spec.Environment.Name) env, err := fissionClient.Environments(metav1.NamespaceDefault).Get(pkg.Spec.Environment.Name)
if err != nil { if err != nil {
e := fmt.Sprintf("Error getting environment TPR info: %v", err) e := fmt.Sprintf("Error getting environment CRD info: %v", err)
log.Println(e) log.Println(e)
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil) updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
return e, fission.MakeError(500, e) return e, fission.MakeError(500, e)
@@ -134,17 +141,18 @@ func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes
log.Printf("Start updating info of package: %v", pkg.Metadata.Name) log.Printf("Start updating info of package: %v", pkg.Metadata.Name)
// update package status and also build logs // update package status and also build logs
newPkgRV, err := updatePackage(fissionClient, pkg, newPkgRV, err = updatePackage(fissionClient, pkg,
fission.BuildStatusSucceeded, buildResp.BuildLogs, uploadResp) fission.BuildStatusSucceeded, buildResp.BuildLogs, uploadResp)
pkg.Metadata.ResourceVersion = newPkgRV
if err != nil { if err != nil {
e := fmt.Sprintf("Error creating deployment package TPR resource: %v", err) e := fmt.Sprintf("Error creating deployment package CRD resource: %v", err)
log.Println(e) log.Println(e)
updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil) updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil)
return e, fission.MakeError(500, e) return e, fission.MakeError(500, e)
} }
fnList, err := fissionClient. fnList, err := fissionClient.
Functions(api.NamespaceDefault).List(api.ListOptions{}) Functions(metav1.NamespaceDefault).List(metav1.ListOptions{})
if err != nil { if err != nil {
e := fmt.Sprintf("Error getting function list: %v", err) e := fmt.Sprintf("Error getting function list: %v", err)
log.Println(e) log.Println(e)
@@ -159,7 +167,7 @@ func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes
fn.Spec.Package.PackageRef.Namespace == pkg.Metadata.Namespace && fn.Spec.Package.PackageRef.Namespace == pkg.Metadata.Namespace &&
fn.Spec.Package.PackageRef.ResourceVersion != pkg.Metadata.ResourceVersion { fn.Spec.Package.PackageRef.ResourceVersion != pkg.Metadata.ResourceVersion {
fn.Spec.Package.PackageRef.ResourceVersion = newPkgRV fn.Spec.Package.PackageRef.ResourceVersion = newPkgRV
// update TPR // update CRD
_, err = fissionClient.Functions(fn.Metadata.Namespace).Update(&fn) _, err = fissionClient.Functions(fn.Metadata.Namespace).Update(&fn)
if err != nil { if err != nil {
e := fmt.Sprintf("Error updating function package resource version: %v", err) e := fmt.Sprintf("Error updating function package resource version: %v", err)
@@ -175,17 +183,10 @@ func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes
return buildResp.BuildLogs, nil return buildResp.BuildLogs, nil
} }
func updatePackage(fissionClient *tpr.FissionClient, func updatePackage(fissionClient *crd.FissionClient,
pkg *tpr.Package, status fission.BuildStatus, buildLogs string, pkg *crd.Package, status fission.BuildStatus, buildLogs string,
uploadResp *fetcher.UploadResponse) (string, error) { uploadResp *fetcher.UploadResponse) (string, error) {
// 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 empty
// string to skip resource version check.
pkg.Metadata.ResourceVersion = ""
pkg.Status = fission.PackageStatus{ pkg.Status = fission.PackageStatus{
BuildStatus: status, BuildStatus: status,
BuildLog: buildLogs, BuildLog: buildLogs,
@@ -200,7 +201,7 @@ func updatePackage(fissionClient *tpr.FissionClient,
} }
// update package spec // update package spec
pkg, err := fissionClient.Packages(api.NamespaceDefault).Update(pkg) pkg, err := fissionClient.Packages(metav1.NamespaceDefault).Update(pkg)
if err != nil { if err != nil {
log.Printf("Error updating package: %v", err) log.Printf("Error updating package: %v", err)
return "", err return "", err
+70 -60
View File
@@ -22,15 +22,15 @@ import (
"os" "os"
"time" "time"
"k8s.io/client-go/1.5/kubernetes" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/api" "k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/1.5/pkg/api/v1" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/1.5/pkg/apis/extensions/v1beta1" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/1.5/pkg/labels" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/1.5/pkg/util/intstr" apiv1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/1.5/pkg/watch" "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
type requestType int type requestType int
@@ -45,15 +45,15 @@ const (
type ( type (
builderInfo struct { builderInfo struct {
envMetadata *api.ObjectMeta envMetadata *metav1.ObjectMeta
deployment *v1beta1.Deployment deployment *v1beta1.Deployment
service *v1.Service service *apiv1.Service
} }
envwRequest struct { envwRequest struct {
requestType requestType
env *tpr.Environment env *crd.Environment
envList []tpr.Environment envList []crd.Environment
respChan chan envwResponse respChan chan envwResponse
} }
@@ -66,14 +66,14 @@ type (
cache map[string]*builderInfo cache map[string]*builderInfo
requestChan chan envwRequest requestChan chan envwRequest
builderNamespace string builderNamespace string
fissionClient *tpr.FissionClient fissionClient *crd.FissionClient
kubernetesClient *kubernetes.Clientset kubernetesClient *kubernetes.Clientset
fetcherImage string fetcherImage string
fetcherImagePullPolicy v1.PullPolicy fetcherImagePullPolicy apiv1.PullPolicy
} }
) )
func makeEnvironmentWatcher(fissionClient *tpr.FissionClient, func makeEnvironmentWatcher(fissionClient *crd.FissionClient,
kubernetesClient *kubernetes.Clientset, builderNamespace string) *environmentWatcher { kubernetesClient *kubernetes.Clientset, builderNamespace string) *environmentWatcher {
fetcherImage := os.Getenv("FETCHER_IMAGE") fetcherImage := os.Getenv("FETCHER_IMAGE")
@@ -86,14 +86,14 @@ func makeEnvironmentWatcher(fissionClient *tpr.FissionClient,
fetcherImagePullPolicy = "IfNotPresent" fetcherImagePullPolicy = "IfNotPresent"
} }
var pullPolicy v1.PullPolicy var pullPolicy apiv1.PullPolicy
switch fetcherImagePullPolicy { switch fetcherImagePullPolicy {
case "Always": case "Always":
pullPolicy = v1.PullAlways pullPolicy = apiv1.PullAlways
case "Never": case "Never":
pullPolicy = v1.PullNever pullPolicy = apiv1.PullNever
default: default:
pullPolicy = v1.PullIfNotPresent pullPolicy = apiv1.PullIfNotPresent
} }
envWatcher := &environmentWatcher{ envWatcher := &environmentWatcher{
@@ -125,7 +125,7 @@ func (envw *environmentWatcher) getLabels(envName string, envResourceVersion str
func (envw *environmentWatcher) watchEnvironments() { func (envw *environmentWatcher) watchEnvironments() {
rv := "" rv := ""
for { for {
wi, err := envw.fissionClient.Environments(api.NamespaceAll).Watch(api.ListOptions{ wi, err := envw.fissionClient.Environments(metav1.NamespaceAll).Watch(metav1.ListOptions{
ResourceVersion: rv, ResourceVersion: rv,
}) })
if err != nil { if err != nil {
@@ -144,7 +144,7 @@ func (envw *environmentWatcher) watchEnvironments() {
time.Sleep(time.Second) time.Sleep(time.Second)
break break
} }
env := ev.Object.(*tpr.Environment) env := ev.Object.(*crd.Environment)
rv = env.Metadata.ResourceVersion rv = env.Metadata.ResourceVersion
envw.sync() envw.sync()
} }
@@ -152,9 +152,9 @@ func (envw *environmentWatcher) watchEnvironments() {
} }
func (envw *environmentWatcher) sync() { func (envw *environmentWatcher) sync() {
envList, err := envw.fissionClient.Environments(api.NamespaceAll).List(api.ListOptions{}) envList, err := envw.fissionClient.Environments(metav1.NamespaceAll).List(metav1.ListOptions{})
if err != nil { if err != nil {
log.Fatalf("Error syncing environment TPR resources: %v", err) log.Fatalf("Error syncing environment CRD resources: %v", err)
} }
// Create environment builders for all environments // Create environment builders for all environments
@@ -191,7 +191,7 @@ func (envw *environmentWatcher) service() {
req.respChan <- envwResponse{builderInfo: builderInfo} req.respChan <- envwResponse{builderInfo: builderInfo}
case CLEANUP_BUILDERS: case CLEANUP_BUILDERS:
latestEnvList := make(map[string]*tpr.Environment) latestEnvList := make(map[string]*crd.Environment)
for i := range req.envList { for i := range req.envList {
env := req.envList[i] env := req.envList[i]
key := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion) key := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion)
@@ -201,7 +201,7 @@ func (envw *environmentWatcher) service() {
// If an environment is deleted when builder manager down, // If an environment is deleted when builder manager down,
// the builder belongs to the environment will be out-of- // the builder belongs to the environment will be out-of-
// control (an orphan builder) since there is no record in // control (an orphan builder) since there is no record in
// cache and TPR. We need to iterate over the services & // cache and CRD. We need to iterate over the services &
// deployments to remove both normal and orphan builders. // deployments to remove both normal and orphan builders.
svcList, err := envw.getBuilderServiceList(nil) svcList, err := envw.getBuilderServiceList(nil)
@@ -241,7 +241,7 @@ func (envw *environmentWatcher) service() {
} }
} }
func (envw *environmentWatcher) getEnvBuilder(env *tpr.Environment) (*builderInfo, error) { func (envw *environmentWatcher) getEnvBuilder(env *crd.Environment) (*builderInfo, error) {
respChan := make(chan envwResponse) respChan := make(chan envwResponse)
envw.requestChan <- envwRequest{ envw.requestChan <- envwRequest{
requestType: GET_BUILDER, requestType: GET_BUILDER,
@@ -252,15 +252,15 @@ func (envw *environmentWatcher) getEnvBuilder(env *tpr.Environment) (*builderInf
return resp.builderInfo, resp.err return resp.builderInfo, resp.err
} }
func (envw *environmentWatcher) cleanupEnvBuilders(envs []tpr.Environment) { func (envw *environmentWatcher) cleanupEnvBuilders(envs []crd.Environment) {
envw.requestChan <- envwRequest{ envw.requestChan <- envwRequest{
requestType: CLEANUP_BUILDERS, requestType: CLEANUP_BUILDERS,
envList: envs, envList: envs,
} }
} }
func (envw *environmentWatcher) createBuilder(env *tpr.Environment) (*builderInfo, error) { func (envw *environmentWatcher) createBuilder(env *crd.Environment) (*builderInfo, error) {
var svc *v1.Service var svc *apiv1.Service
var deploy *v1beta1.Deployment var deploy *v1beta1.Deployment
sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion) sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion)
@@ -269,22 +269,32 @@ func (envw *environmentWatcher) createBuilder(env *tpr.Environment) (*builderInf
if err != nil { if err != nil {
return nil, err return nil, err
} }
// there should be only one service in svcList
if len(svcList) == 0 { if len(svcList) == 0 {
svc, err = envw.createBuilderService(env) svc, err = envw.createBuilderService(env)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error creating builder service: %v", err) 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) deployList, err := envw.getBuilderDeploymentList(sel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// there should be only one deploy in deployList
if len(deployList) == 0 { if len(deployList) == 0 {
deploy, err = envw.createBuilderDeployment(env) deploy, err = envw.createBuilderDeployment(env)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error creating builder deployment: %v", err) 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{ return &builderInfo{
@@ -305,7 +315,7 @@ func (envw *environmentWatcher) deleteBuilderService(sel map[string]string) erro
// cascading deletion // cascading deletion
// https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ // https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/
falseVal := false falseVal := false
delOpt := &api.DeleteOptions{ delOpt := &metav1.DeleteOptions{
OrphanDependents: &falseVal, OrphanDependents: &falseVal,
} }
@@ -328,11 +338,11 @@ func (envw *environmentWatcher) deleteBuilderDeployment(sel map[string]string) e
log.Printf("Removing builder deployment: %v", deploy.ObjectMeta.Name) log.Printf("Removing builder deployment: %v", deploy.ObjectMeta.Name)
falseVal := false falseVal := false
delOpt := &api.DeleteOptions{ delOpt := &metav1.DeleteOptions{
OrphanDependents: &falseVal, OrphanDependents: &falseVal,
} }
err = envw.kubernetesClient. err = envw.kubernetesClient.ExtensionsV1beta1().
Deployments(envw.builderNamespace). Deployments(envw.builderNamespace).
Delete(deploy.ObjectMeta.Name, delOpt) Delete(deploy.ObjectMeta.Name, delOpt)
if err != nil { if err != nil {
@@ -342,10 +352,10 @@ func (envw *environmentWatcher) deleteBuilderDeployment(sel map[string]string) e
return nil return nil
} }
func (envw *environmentWatcher) getBuilderServiceList(sel map[string]string) ([]v1.Service, error) { func (envw *environmentWatcher) getBuilderServiceList(sel map[string]string) ([]apiv1.Service, error) {
svcList, err := envw.kubernetesClient.Services(envw.builderNamespace).List( svcList, err := envw.kubernetesClient.Services(envw.builderNamespace).List(
api.ListOptions{ metav1.ListOptions{
LabelSelector: labels.Set(sel).AsSelector(), LabelSelector: labels.Set(sel).AsSelector().String(),
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("Error getting builder service list: %v", err) return nil, fmt.Errorf("Error getting builder service list: %v", err)
@@ -353,22 +363,22 @@ func (envw *environmentWatcher) getBuilderServiceList(sel map[string]string) ([]
return svcList.Items, nil return svcList.Items, nil
} }
func (envw *environmentWatcher) createBuilderService(env *tpr.Environment) (*v1.Service, error) { func (envw *environmentWatcher) createBuilderService(env *crd.Environment) (*apiv1.Service, error) {
name := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion) name := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion)
sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion) sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion)
service := v1.Service{ service := apiv1.Service{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Namespace: envw.builderNamespace, Namespace: envw.builderNamespace,
Name: name, Name: name,
Labels: sel, Labels: sel,
}, },
Spec: v1.ServiceSpec{ Spec: apiv1.ServiceSpec{
Selector: sel, Selector: sel,
Type: v1.ServiceTypeClusterIP, Type: apiv1.ServiceTypeClusterIP,
Ports: []v1.ServicePort{ Ports: []apiv1.ServicePort{
{ {
Name: "fetcher-port", Name: "fetcher-port",
Protocol: v1.ProtocolTCP, Protocol: apiv1.ProtocolTCP,
Port: 8000, Port: 8000,
TargetPort: intstr.IntOrString{ TargetPort: intstr.IntOrString{
Type: intstr.Int, Type: intstr.Int,
@@ -377,7 +387,7 @@ func (envw *environmentWatcher) createBuilderService(env *tpr.Environment) (*v1.
}, },
{ {
Name: "builder-port", Name: "builder-port",
Protocol: v1.ProtocolTCP, Protocol: apiv1.ProtocolTCP,
Port: 8001, Port: 8001,
TargetPort: intstr.IntOrString{ TargetPort: intstr.IntOrString{
Type: intstr.Int, Type: intstr.Int,
@@ -396,9 +406,9 @@ func (envw *environmentWatcher) createBuilderService(env *tpr.Environment) (*v1.
} }
func (envw *environmentWatcher) getBuilderDeploymentList(sel map[string]string) ([]v1beta1.Deployment, error) { func (envw *environmentWatcher) getBuilderDeploymentList(sel map[string]string) ([]v1beta1.Deployment, error) {
deployList, err := envw.kubernetesClient.Deployments(envw.builderNamespace).List( deployList, err := envw.kubernetesClient.ExtensionsV1beta1().Deployments(envw.builderNamespace).List(
api.ListOptions{ metav1.ListOptions{
LabelSelector: labels.Set(sel).AsSelector(), LabelSelector: labels.Set(sel).AsSelector().String(),
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("Error getting builder deployment list: %v", err) return nil, fmt.Errorf("Error getting builder deployment list: %v", err)
@@ -406,42 +416,42 @@ func (envw *environmentWatcher) getBuilderDeploymentList(sel map[string]string)
return deployList.Items, nil return deployList.Items, nil
} }
func (envw *environmentWatcher) createBuilderDeployment(env *tpr.Environment) (*v1beta1.Deployment, error) { func (envw *environmentWatcher) createBuilderDeployment(env *crd.Environment) (*v1beta1.Deployment, error) {
sharedMountPath := "/package" sharedMountPath := "/package"
name := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion) name := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion)
sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion) sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion)
var replicas int32 = 1 var replicas int32 = 1
deployment := &v1beta1.Deployment{ deployment := &v1beta1.Deployment{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Namespace: envw.builderNamespace, Namespace: envw.builderNamespace,
Name: name, Name: name,
Labels: sel, Labels: sel,
}, },
Spec: v1beta1.DeploymentSpec{ Spec: v1beta1.DeploymentSpec{
Replicas: &replicas, Replicas: &replicas,
Selector: &v1beta1.LabelSelector{ Selector: &metav1.LabelSelector{
MatchLabels: sel, MatchLabels: sel,
}, },
Template: v1.PodTemplateSpec{ Template: apiv1.PodTemplateSpec{
ObjectMeta: v1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Labels: sel, Labels: sel,
}, },
Spec: v1.PodSpec{ Spec: apiv1.PodSpec{
Volumes: []v1.Volume{ Volumes: []apiv1.Volume{
{ {
Name: "package", Name: "package",
VolumeSource: v1.VolumeSource{ VolumeSource: apiv1.VolumeSource{
EmptyDir: &v1.EmptyDirVolumeSource{}, EmptyDir: &apiv1.EmptyDirVolumeSource{},
}, },
}, },
}, },
Containers: []v1.Container{ Containers: []apiv1.Container{
{ {
Name: "builder", Name: "builder",
Image: env.Spec.Builder.Image, Image: env.Spec.Builder.Image,
ImagePullPolicy: v1.PullAlways, ImagePullPolicy: apiv1.PullAlways,
TerminationMessagePath: "/dev/termination-log", TerminationMessagePath: "/dev/termination-log",
VolumeMounts: []v1.VolumeMount{ VolumeMounts: []apiv1.VolumeMount{
{ {
Name: "package", Name: "package",
MountPath: sharedMountPath, MountPath: sharedMountPath,
@@ -454,7 +464,7 @@ func (envw *environmentWatcher) createBuilderDeployment(env *tpr.Environment) (*
Image: envw.fetcherImage, Image: envw.fetcherImage,
ImagePullPolicy: envw.fetcherImagePullPolicy, ImagePullPolicy: envw.fetcherImagePullPolicy,
TerminationMessagePath: "/dev/termination-log", TerminationMessagePath: "/dev/termination-log",
VolumeMounts: []v1.VolumeMount{ VolumeMounts: []apiv1.VolumeMount{
{ {
Name: "package", Name: "package",
MountPath: sharedMountPath, MountPath: sharedMountPath,
@@ -469,7 +479,7 @@ func (envw *environmentWatcher) createBuilderDeployment(env *tpr.Environment) (*
}, },
} }
log.Printf("Creating builder deployment: %v", envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion)) log.Printf("Creating builder deployment: %v", envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion))
_, err := envw.kubernetesClient.Deployments(envw.builderNamespace).Create(deployment) _, err := envw.kubernetesClient.ExtensionsV1beta1().Deployments(envw.builderNamespace).Create(deployment)
if err != nil { if err != nil {
return nil, err return nil, err
} }
+10 -10
View File
@@ -20,24 +20,24 @@ import (
"log" "log"
"time" "time"
"k8s.io/client-go/1.5/kubernetes" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/api" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/1.5/pkg/watch" "k8s.io/client-go/kubernetes"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
type ( type (
packageWatcher struct { packageWatcher struct {
fissionClient *tpr.FissionClient fissionClient *crd.FissionClient
kubernetesClient *kubernetes.Clientset kubernetesClient *kubernetes.Clientset
builderNamespace string builderNamespace string
storageSvcUrl string storageSvcUrl string
} }
) )
func makePackageWatcher(fissionClient *tpr.FissionClient, func makePackageWatcher(fissionClient *crd.FissionClient,
kubernetesClient *kubernetes.Clientset, builderNamespace string, storageSvcUrl string) *packageWatcher { kubernetesClient *kubernetes.Clientset, builderNamespace string, storageSvcUrl string) *packageWatcher {
pkgw := &packageWatcher{ pkgw := &packageWatcher{
fissionClient: fissionClient, fissionClient: fissionClient,
@@ -48,7 +48,7 @@ func makePackageWatcher(fissionClient *tpr.FissionClient,
return pkgw return pkgw
} }
func (pkgw *packageWatcher) build(pkgMetadata api.ObjectMeta) { func (pkgw *packageWatcher) build(pkgMetadata metav1.ObjectMeta) {
buildReq := BuildRequest{ buildReq := BuildRequest{
Package: pkgMetadata, Package: pkgMetadata,
} }
@@ -62,11 +62,11 @@ func (pkgw *packageWatcher) build(pkgMetadata api.ObjectMeta) {
func (pkgw *packageWatcher) watchPackages() { func (pkgw *packageWatcher) watchPackages() {
rv := "" rv := ""
for { for {
wi, err := pkgw.fissionClient.Packages(api.NamespaceDefault).Watch(api.ListOptions{ wi, err := pkgw.fissionClient.Packages(metav1.NamespaceDefault).Watch(metav1.ListOptions{
ResourceVersion: rv, ResourceVersion: rv,
}) })
if err != nil { if err != nil {
log.Fatalf("Error watching package TPR resources: %v", err) log.Fatalf("Error watching package CRD resources: %v", err)
} }
for { for {
@@ -79,7 +79,7 @@ func (pkgw *packageWatcher) watchPackages() {
time.Sleep(time.Second) time.Sleep(time.Second)
break break
} }
pkg := ev.Object.(*tpr.Package) pkg := ev.Object.(*crd.Package)
rv = pkg.Metadata.ResourceVersion rv = pkg.Metadata.ResourceVersion
// only do build for packages in pending state // only do build for packages in pending state
+1 -1
View File
@@ -5,7 +5,7 @@
## Prerequisites ## Prerequisites
- Kubernetes 1.6+ with Beta APIs enabled - Kubernetes 1.8 or later
## Helm charts ## Helm charts
+2 -2
View File
@@ -1,6 +1,6 @@
apiVersion: v1 apiVersion: v1
name: fission-all name: fission-all
version: 0.3.0 version: 0.4.0
description: Fission is a fast serverless framework for Kubernetes. description: Fission is a fast serverless framework for Kubernetes.
keywords: keywords:
- fission - fission
@@ -12,4 +12,4 @@ maintainers:
- name: Ta Ching Chen - name: Ta Ching Chen
email: contact@tachingchen.com email: contact@tachingchen.com
engine: gotpl engine: gotpl
appVersion: 0.3.0 appVersion: 0.4.0
+3 -3
View File
@@ -1,13 +1,13 @@
1. Install the client CLI. 1. Install the client CLI.
Mac: Mac:
$ 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/ $ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
Linux: Linux:
$ 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/ $ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
Windows: 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/0.3.0/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.0/fission-cli-windows.exe
2. Set the FISSION_URL and FISSION_ROUTER environment variables. 2. Set the FISSION_URL and FISSION_ROUTER environment variables.
+7 -24
View File
@@ -131,7 +131,7 @@ roleRef:
kind: ClusterRoleBinding kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1 apiVersion: rbac.authorization.k8s.io/v1beta1
metadata: metadata:
name: fission-tpr name: fission-crd
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: fission-svc name: fission-svc
@@ -152,7 +152,7 @@ metadata:
kind: ClusterRoleBinding kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1 apiVersion: rbac.authorization.k8s.io/v1beta1
metadata: metadata:
name: fission-fetcher-tpr name: fission-fetcher-crd
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: fission-fetcher name: fission-fetcher
@@ -173,7 +173,7 @@ metadata:
kind: ClusterRoleBinding kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1 apiVersion: rbac.authorization.k8s.io/v1beta1
metadata: metadata:
name: fission-builder-tpr name: fission-builder-crd
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: fission-builder name: fission-builder
@@ -400,25 +400,6 @@ spec:
svc: logger svc: logger
spec: spec:
containers: containers:
- name: logger
image: "{{ .Values.image }}:{{ .Values.imageTag }}"
imagePullPolicy: {{ .Values.pullPolicy }}
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 - name: fluentd
image: {{ .Values.logger.fluentdImage }} image: {{ .Values.logger.fluentdImage }}
imagePullPolicy: {{ .Values.pullPolicy }} imagePullPolicy: {{ .Values.pullPolicy }}
@@ -439,9 +420,11 @@ spec:
secretKeyRef: secretKeyRef:
name: influxdb name: influxdb
key: password key: password
- name: FLUENTD_PATH
value: /var/log/containers/*{{.Values.functionNamespace}}*.log
volumeMounts: volumeMounts:
- name: container-log - name: container-log
mountPath: /var/log/containers mountPath: /var/log/
readOnly: true readOnly: true
- name: docker-log - name: docker-log
mountPath: /var/lib/docker/containers mountPath: /var/lib/docker/containers
@@ -453,7 +436,7 @@ spec:
volumes: volumes:
- name: container-log - name: container-log
hostPath: hostPath:
path: /var/log/containers path: /var/log/
- name: docker-log - name: docker-log
hostPath: hostPath:
path: /var/lib/docker/containers path: /var/lib/docker/containers
+6
View File
@@ -10,7 +10,9 @@ spec:
ports: ports:
- port: 80 - port: 80
targetPort: 8888 targetPort: 8888
{{ if eq .Values.serviceType "NodePort" }}
nodePort: {{ .Values.routerPort }} nodePort: {{ .Values.routerPort }}
{{ end }}
selector: selector:
svc: router svc: router
@@ -27,7 +29,9 @@ spec:
ports: ports:
- port: 80 - port: 80
targetPort: 8888 targetPort: 8888
{{ if eq .Values.serviceType "NodePort" }}
nodePort: {{ .Values.controllerPort }} nodePort: {{ .Values.controllerPort }}
{{ end }}
selector: selector:
svc: controller svc: controller
@@ -44,7 +48,9 @@ spec:
ports: ports:
- port: 4222 - port: 4222
targetPort: 4222 targetPort: 4222
{{ if eq .Values.serviceType "NodePort" }}
nodePort: {{ .Values.natsStreamingPort }} nodePort: {{ .Values.natsStreamingPort }}
{{ end }}
selector: selector:
svc: nats-streaming svc: nats-streaming
+2 -2
View File
@@ -13,13 +13,13 @@ image: fission/fission-bundle
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
## Fission image version ## Fission image version
imageTag: 0.3.0 imageTag: 0.4.0
## Fission fetcher repository ## Fission fetcher repository
fetcherImage: fission/fetcher fetcherImage: fission/fetcher
## Fission fetcher image version ## Fission fetcher image version
fetcherImageTag: 0.3.0 fetcherImageTag: 0.4.0
## Port at which Fission controller service should be exposed ## Port at which Fission controller service should be exposed
controllerPort: 31313 controllerPort: 31313
+2 -2
View File
@@ -1,6 +1,6 @@
apiVersion: v1 apiVersion: v1
name: fission-core name: fission-core
version: 0.3.0 version: 0.4.0
description: Fission is a fast serverless framework for Kubernetes. description: Fission is a fast serverless framework for Kubernetes.
keywords: keywords:
- fission - fission
@@ -12,4 +12,4 @@ maintainers:
- name: Ta Ching Chen - name: Ta Ching Chen
email: contact@tachingchen.com email: contact@tachingchen.com
engine: gotpl engine: gotpl
appVersion: 0.3.0 appVersion: 0.4.0
+3 -3
View File
@@ -1,13 +1,13 @@
1. Install the client CLI. 1. Install the client CLI.
Mac: Mac:
$ 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/ $ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/
Linux: Linux:
$ 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/ $ curl -Lo fission https://github.com/fission/fission/releases/download/0.4.0/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/
Windows: 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/0.3.0/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.0/fission-cli-windows.exe
2. Set the FISSION_URL and FISSION_ROUTER environment variables. 2. Set the FISSION_URL and FISSION_ROUTER environment variables.
@@ -131,7 +131,7 @@ roleRef:
kind: ClusterRoleBinding kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1 apiVersion: rbac.authorization.k8s.io/v1beta1
metadata: metadata:
name: fission-tpr name: fission-crd
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: fission-svc name: fission-svc
@@ -152,7 +152,7 @@ metadata:
kind: ClusterRoleBinding kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1 apiVersion: rbac.authorization.k8s.io/v1beta1
metadata: metadata:
name: fission-fetcher-tpr name: fission-fetcher-crd
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: fission-fetcher name: fission-fetcher
@@ -173,7 +173,7 @@ metadata:
kind: ClusterRoleBinding kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1 apiVersion: rbac.authorization.k8s.io/v1beta1
metadata: metadata:
name: fission-builder-tpr name: fission-builder-crd
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: fission-builder name: fission-builder
+4
View File
@@ -10,7 +10,9 @@ spec:
ports: ports:
- port: 80 - port: 80
targetPort: 8888 targetPort: 8888
{{ if eq .Values.serviceType "NodePort" }}
nodePort: {{ .Values.routerPort }} nodePort: {{ .Values.routerPort }}
{{ end }}
selector: selector:
svc: router svc: router
@@ -27,7 +29,9 @@ spec:
ports: ports:
- port: 80 - port: 80
targetPort: 8888 targetPort: 8888
{{ if eq .Values.serviceType "NodePort" }}
nodePort: {{ .Values.controllerPort }} nodePort: {{ .Values.controllerPort }}
{{ end }}
selector: selector:
svc: controller svc: controller
+2 -2
View File
@@ -10,7 +10,7 @@ serviceType: LoadBalancer
image: fission/fission-bundle image: fission/fission-bundle
## Fission image version ## Fission image version
imageTag: 0.3.0 imageTag: 0.4.0
## Image pull policy ## Image pull policy
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
@@ -19,7 +19,7 @@ pullPolicy: IfNotPresent
fetcherImage: fission/fetcher fetcherImage: fission/fetcher
## Fission fetcher image version ## Fission fetcher image version
fetcherImageTag: 0.3.0 fetcherImageTag: 0.4.0
## Port at which Fission controller service should be exposed ## Port at which Fission controller service should be exposed
controllerPort: 31313 controllerPort: 31313
+10 -6
View File
@@ -26,16 +26,18 @@ import (
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/gorilla/mux" "github.com/gorilla/mux"
log "github.com/sirupsen/logrus" 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"
"github.com/fission/fission/crd"
"github.com/fission/fission/fission/logdb" "github.com/fission/fission/fission/logdb"
"github.com/fission/fission/tpr"
) )
type ( type (
API struct { API struct {
fissionClient *tpr.FissionClient fissionClient *crd.FissionClient
kubernetesClient *kubernetes.Clientset
storageServiceUrl string storageServiceUrl string
builderManagerUrl string builderManagerUrl string
workflowApiUrl string workflowApiUrl string
@@ -49,7 +51,7 @@ type (
) )
func MakeAPI() (*API, error) { func MakeAPI() (*API, error) {
api, err := makeTPRBackedAPI() api, err := makeCRDBackedAPI()
u := os.Getenv("STORAGE_SERVICE_URL") u := os.Getenv("STORAGE_SERVICE_URL")
if len(u) > 0 { if len(u) > 0 {
@@ -118,7 +120,7 @@ func (api *API) getLogDBConfig(dbType string) logDBConfig {
func (api *API) HomeHandler(w http.ResponseWriter, r *http.Request) { func (api *API) HomeHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8") w.Header().Set("Content-Type", "application/json; charset=utf-8")
fmt.Fprintf(w, "{\"message\": \"Fission API\", \"version\": \"0.3.0\"}\n") fmt.Fprintf(w, "{\"message\": \"Fission API\", \"version\": \"0.4.0\"}\n")
} }
func (api *API) ApiVersionMismatchHandler(w http.ResponseWriter, r *http.Request) { func (api *API) ApiVersionMismatchHandler(w http.ResponseWriter, r *http.Request) {
@@ -174,10 +176,12 @@ func (api *API) Serve(port int) {
r.HandleFunc("/v2/triggers/messagequeue/{mqTrigger}", api.MessageQueueTriggerApiUpdate).Methods("PUT") r.HandleFunc("/v2/triggers/messagequeue/{mqTrigger}", api.MessageQueueTriggerApiUpdate).Methods("PUT")
r.HandleFunc("/v2/triggers/messagequeue/{mqTrigger}", api.MessageQueueTriggerApiDelete).Methods("DELETE") 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/{dbType}", api.FunctionLogsApiPost).Methods("POST")
r.HandleFunc("/proxy/storage/v1/archive", api.StorageServiceProxy) r.HandleFunc("/proxy/storage/v1/archive", api.StorageServiceProxy)
r.HandleFunc("/proxy/buildermgr/v1/build", api.BuilderManagerBuildProxy) r.HandleFunc("/proxy/buildermgr/v1/build", api.BuilderManagerBuildProxy)
r.HandleFunc("/proxy/buildermgr/v1/builder", api.BuilderManagerEnvBuilderProxy) r.HandleFunc("/proxy/logs/{function}", api.FunctionPodLogs).Methods("POST")
r.HandleFunc("/proxy/workflows-apiserver/{path:.*}", api.WorkflowApiserverProxy) r.HandleFunc("/proxy/workflows-apiserver/{path:.*}", api.WorkflowApiserverProxy)
address := fmt.Sprintf(":%v", port) address := fmt.Sprintf(":%v", port)
+50 -45
View File
@@ -18,6 +18,7 @@ package controller
import ( import (
"flag" "flag"
"fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
@@ -25,11 +26,11 @@ import (
"testing" "testing"
"time" "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"
"github.com/fission/fission/controller/client" "github.com/fission/fission/controller/client"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
var g struct { var g struct {
@@ -72,13 +73,10 @@ func assertCronSpecFails(err error) {
} }
func TestFunctionApi(t *testing.T) { func TestFunctionApi(t *testing.T) {
name1 := "foo" testFunc := &crd.Function{
name2 := "bar" Metadata: metav1.ObjectMeta{
Name: "foo",
testFunc := &tpr.Function{ Namespace: metav1.NamespaceDefault,
Metadata: api.ObjectMeta{
Name: name1,
Namespace: api.NamespaceDefault,
}, },
Spec: fission.FunctionSpec{ Spec: fission.FunctionSpec{
Environment: fission.EnvironmentReference{ 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, Name: testFunc.Metadata.Name,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
assertNotFoundFailure(err, "function") assertNotFoundFailure(err, "function")
_, err = g.client.FunctionCreate(testFunc) m, err := g.client.FunctionCreate(testFunc)
panicIf(err) panicIf(err)
defer func() {
err := g.client.FunctionDelete(m)
panicIf(err)
}()
_, err = g.client.FunctionCreate(testFunc) _, err = g.client.FunctionCreate(testFunc)
assertNameReuseFailure(err, "function") assertNameReuseFailure(err, "function")
testFunc.Metadata.ResourceVersion = m.ResourceVersion
testFunc.Spec.Package.FunctionName = "yyy" testFunc.Spec.Package.FunctionName = "yyy"
_, err = g.client.FunctionUpdate(testFunc) _, err = g.client.FunctionUpdate(testFunc)
panicIf(err) panicIf(err)
testFunc.Metadata.Name = name2 testFunc.Metadata.ResourceVersion = ""
_, err = g.client.FunctionCreate(testFunc) testFunc.Metadata.Name = "bar"
m2, err := g.client.FunctionCreate(testFunc)
panicIf(err) panicIf(err)
defer g.client.FunctionDelete(m2)
funcs, err := g.client.FunctionList() funcs, err := g.client.FunctionList()
panicIf(err) panicIf(err)
assert(len(funcs) == 2, assert(len(funcs) == 2, fmt.Sprintf("created two functions, but found %v", len(funcs)))
"created two functions, but didn't find them")
funcs_url := g.client.Url + "/v2/functions" funcs_url := g.client.Url + "/v2/functions"
resp, err := http.Get(funcs_url) resp, err := http.Get(funcs_url)
@@ -127,18 +131,13 @@ func TestFunctionApi(t *testing.T) {
} }
} }
assert(found, "incorrect response content type") 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) { func TestHTTPTriggerApi(t *testing.T) {
testTrigger := &tpr.Httptrigger{ testTrigger := &crd.HTTPTrigger{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.HTTPTriggerSpec{ Spec: fission.HTTPTriggerSpec{
RelativeURL: "/hello", 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, Name: testTrigger.Metadata.Name,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
assertNotFoundFailure(err, "httptrigger") assertNotFoundFailure(err, "httptrigger")
@@ -165,10 +164,12 @@ func TestHTTPTriggerApi(t *testing.T) {
panicIf(err) panicIf(err)
assert(testTrigger.Spec == tr.Spec, "trigger should match after reading") assert(testTrigger.Spec == tr.Spec, "trigger should match after reading")
testTrigger.Metadata.ResourceVersion = m.ResourceVersion
testTrigger.Spec.RelativeURL = "/hi" testTrigger.Spec.RelativeURL = "/hi"
_, err = g.client.HTTPTriggerUpdate(testTrigger) _, err = g.client.HTTPTriggerUpdate(testTrigger)
panicIf(err) panicIf(err)
testTrigger.Metadata.ResourceVersion = ""
testTrigger.Metadata.Name = "yyy" testTrigger.Metadata.Name = "yyy"
_, err = g.client.HTTPTriggerCreate(testTrigger) _, err = g.client.HTTPTriggerCreate(testTrigger)
assert(err != nil, "duplicate trigger should not be allowed") assert(err != nil, "duplicate trigger should not be allowed")
@@ -180,14 +181,14 @@ func TestHTTPTriggerApi(t *testing.T) {
ts, err := g.client.HTTPTriggerList() ts, err := g.client.HTTPTriggerList()
panicIf(err) 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) { func TestEnvironmentApi(t *testing.T) {
testEnv := &tpr.Environment{ testEnv := &crd.Environment{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.EnvironmentSpec{ Spec: fission.EnvironmentSpec{
Runtime: fission.Runtime{ 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, Name: testEnv.Metadata.Name,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
assertNotFoundFailure(err, "environment") assertNotFoundFailure(err, "environment")
@@ -212,10 +213,12 @@ func TestEnvironmentApi(t *testing.T) {
panicIf(err) panicIf(err)
assert(testEnv.Spec == e.Spec, "env should match after reading") assert(testEnv.Spec == e.Spec, "env should match after reading")
testEnv.Metadata.ResourceVersion = m.ResourceVersion
testEnv.Spec.Runtime.Image = "another-img" testEnv.Spec.Runtime.Image = "another-img"
_, err = g.client.EnvironmentUpdate(testEnv) _, err = g.client.EnvironmentUpdate(testEnv)
panicIf(err) panicIf(err)
testEnv.Metadata.ResourceVersion = ""
testEnv.Metadata.Name = "bar" testEnv.Metadata.Name = "bar"
m2, err := g.client.EnvironmentCreate(testEnv) m2, err := g.client.EnvironmentCreate(testEnv)
panicIf(err) panicIf(err)
@@ -223,14 +226,14 @@ func TestEnvironmentApi(t *testing.T) {
ts, err := g.client.EnvironmentList() ts, err := g.client.EnvironmentList()
panicIf(err) 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) { func TestWatchApi(t *testing.T) {
testWatch := &tpr.Kuberneteswatchtrigger{ testWatch := &crd.KubernetesWatchTrigger{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: "xxx", Name: "xxx",
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.KubernetesWatchTriggerSpec{ Spec: fission.KubernetesWatchTriggerSpec{
Namespace: "default", 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, Name: testWatch.Metadata.Name,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
assertNotFoundFailure(err, "watch") assertNotFoundFailure(err, "watch")
@@ -267,14 +270,14 @@ func TestWatchApi(t *testing.T) {
ws, err := g.client.WatchList() ws, err := g.client.WatchList()
panicIf(err) 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) { func TestTimeTriggerApi(t *testing.T) {
testTrigger := &tpr.Timetrigger{ testTrigger := &crd.TimeTrigger{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: "xxx", Name: "xxx",
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.TimeTriggerSpec{ Spec: fission.TimeTriggerSpec{
Cron: "0 30 * * * *", 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") assertNotFoundFailure(err, "trigger")
m, err := g.client.TimeTriggerCreate(testTrigger) m, err := g.client.TimeTriggerCreate(testTrigger)
@@ -298,10 +301,12 @@ func TestTimeTriggerApi(t *testing.T) {
panicIf(err) panicIf(err)
assert(testTrigger.Spec == tr.Spec, "trigger should match after reading") assert(testTrigger.Spec == tr.Spec, "trigger should match after reading")
testTrigger.Metadata.ResourceVersion = m.ResourceVersion
testTrigger.Spec.Cron = "@hourly" testTrigger.Spec.Cron = "@hourly"
_, err = g.client.TimeTriggerUpdate(testTrigger) _, err = g.client.TimeTriggerUpdate(testTrigger)
panicIf(err) panicIf(err)
testTrigger.Metadata.ResourceVersion = ""
testTrigger.Metadata.Name = "yyy" testTrigger.Metadata.Name = "yyy"
testTrigger.Spec.Cron = "Not valid cron spec" testTrigger.Spec.Cron = "Not valid cron spec"
_, err = g.client.TimeTriggerCreate(testTrigger) _, err = g.client.TimeTriggerCreate(testTrigger)
@@ -309,7 +314,7 @@ func TestTimeTriggerApi(t *testing.T) {
ts, err := g.client.TimeTriggerList() ts, err := g.client.TimeTriggerList()
panicIf(err) 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) { func TestMain(m *testing.M) {
@@ -324,7 +329,7 @@ func TestMain(m *testing.M) {
go Start(8888) go Start(8888)
time.Sleep(time.Second) time.Sleep(5 * time.Second)
g.client = client.MakeClient("http://localhost:8888") g.client = client.MakeClient("http://localhost:8888")
resp, err := http.Get("http://localhost:8888/") resp, err := http.Get("http://localhost:8888/")
+2 -14
View File
@@ -26,7 +26,7 @@ import (
func (api *API) BuilderManagerBuildProxy(w http.ResponseWriter, r *http.Request) { func (api *API) BuilderManagerBuildProxy(w http.ResponseWriter, r *http.Request) {
u := api.builderManagerUrl + "/v1/build" u := api.builderManagerUrl + "/v1/build"
proxy, err := api._getBuilderManagerProxy(u) proxy, err := api.getBuilderManagerProxy(u)
if err != nil { if err != nil {
msg := fmt.Sprintf("Failed to establish proxy server: %v", err) msg := fmt.Sprintf("Failed to establish proxy server: %v", err)
log.Println(msg) log.Println(msg)
@@ -36,19 +36,7 @@ func (api *API) BuilderManagerBuildProxy(w http.ResponseWriter, r *http.Request)
proxy.ServeHTTP(w, r) proxy.ServeHTTP(w, r)
} }
func (api *API) BuilderManagerEnvBuilderProxy(w http.ResponseWriter, r *http.Request) { func (api *API) getBuilderManagerProxy(targetUrl string) (*httputil.ReverseProxy, error) {
u := api.builderManagerUrl + "/v1/builder"
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) svcUrl, err := url.Parse(targetUrl)
if err != nil { if err != nil {
return nil, err return nil, err
+11 -11
View File
@@ -22,12 +22,12 @@ import (
"fmt" "fmt"
"net/http" "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) reqbody, err := json.Marshal(env)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -44,7 +44,7 @@ func (c *Client) EnvironmentCreate(env *tpr.Environment) (*api.ObjectMeta, error
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -53,7 +53,7 @@ func (c *Client) EnvironmentCreate(env *tpr.Environment) (*api.ObjectMeta, error
return &m, nil 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("environments/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
@@ -68,7 +68,7 @@ func (c *Client) EnvironmentGet(m *api.ObjectMeta) (*tpr.Environment, error) {
return nil, err return nil, err
} }
var env tpr.Environment var env crd.Environment
err = json.Unmarshal(body, &env) err = json.Unmarshal(body, &env)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -77,7 +77,7 @@ func (c *Client) EnvironmentGet(m *api.ObjectMeta) (*tpr.Environment, error) {
return &env, nil 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) reqbody, err := json.Marshal(env)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -95,7 +95,7 @@ func (c *Client) EnvironmentUpdate(env *tpr.Environment) (*api.ObjectMeta, error
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -103,14 +103,14 @@ func (c *Client) EnvironmentUpdate(env *tpr.Environment) (*api.ObjectMeta, error
return &m, nil 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("environments/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl) 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")) resp, err := http.Get(c.url("environments"))
if err != nil { if err != nil {
return nil, err return nil, err
@@ -122,7 +122,7 @@ func (c *Client) EnvironmentList() ([]tpr.Environment, error) {
return nil, err return nil, err
} }
envs := make([]tpr.Environment, 0) envs := make([]crd.Environment, 0)
err = json.Unmarshal(body, &envs) err = json.Unmarshal(body, &envs)
if err != nil { if err != nil {
return nil, err return nil, err
+12 -12
View File
@@ -22,12 +22,12 @@ import (
"fmt" "fmt"
"net/http" "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) reqbody, err := json.Marshal(f)
if err != nil { if err != nil {
@@ -45,7 +45,7 @@ func (c *Client) FunctionCreate(f *tpr.Function) (*api.ObjectMeta, error) {
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -54,7 +54,7 @@ func (c *Client) FunctionCreate(f *tpr.Function) (*api.ObjectMeta, error) {
return &m, nil 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("functions/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
@@ -69,7 +69,7 @@ func (c *Client) FunctionGet(m *api.ObjectMeta) (*tpr.Function, error) {
return nil, err return nil, err
} }
var f tpr.Function var f crd.Function
err = json.Unmarshal(body, &f) err = json.Unmarshal(body, &f)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -78,7 +78,7 @@ func (c *Client) FunctionGet(m *api.ObjectMeta) (*tpr.Function, error) {
return &f, nil 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("functions/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
relativeUrl += fmt.Sprintf("&deploymentraw=1") relativeUrl += fmt.Sprintf("&deploymentraw=1")
@@ -92,7 +92,7 @@ func (c *Client) FunctionGetRawDeployment(m *api.ObjectMeta) ([]byte, error) {
return c.handleResponse(resp) 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) reqbody, err := json.Marshal(f)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -110,7 +110,7 @@ func (c *Client) FunctionUpdate(f *tpr.Function) (*api.ObjectMeta, error) {
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -118,13 +118,13 @@ func (c *Client) FunctionUpdate(f *tpr.Function) (*api.ObjectMeta, error) {
return &m, nil 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("functions/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl) 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")) resp, err := http.Get(c.url("functions"))
if err != nil { if err != nil {
return nil, err return nil, err
@@ -136,7 +136,7 @@ func (c *Client) FunctionList() ([]tpr.Function, error) {
return nil, err return nil, err
} }
funcs := make([]tpr.Function, 0) funcs := make([]crd.Function, 0)
err = json.Unmarshal(body, &funcs) err = json.Unmarshal(body, &funcs)
if err != nil { if err != nil {
return nil, err return nil, err
+11 -11
View File
@@ -22,12 +22,12 @@ import (
"fmt" "fmt"
"net/http" "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) reqbody, err := json.Marshal(t)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -44,7 +44,7 @@ func (c *Client) HTTPTriggerCreate(t *tpr.Httptrigger) (*api.ObjectMeta, error)
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -53,7 +53,7 @@ func (c *Client) HTTPTriggerCreate(t *tpr.Httptrigger) (*api.ObjectMeta, error)
return &m, nil 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("triggers/http/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
@@ -68,7 +68,7 @@ func (c *Client) HTTPTriggerGet(m *api.ObjectMeta) (*tpr.Httptrigger, error) {
return nil, err return nil, err
} }
var t tpr.Httptrigger var t crd.HTTPTrigger
err = json.Unmarshal(body, &t) err = json.Unmarshal(body, &t)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -77,7 +77,7 @@ func (c *Client) HTTPTriggerGet(m *api.ObjectMeta) (*tpr.Httptrigger, error) {
return &t, nil 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) reqbody, err := json.Marshal(t)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -95,7 +95,7 @@ func (c *Client) HTTPTriggerUpdate(t *tpr.Httptrigger) (*api.ObjectMeta, error)
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -103,13 +103,13 @@ func (c *Client) HTTPTriggerUpdate(t *tpr.Httptrigger) (*api.ObjectMeta, error)
return &m, nil 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("triggers/http/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl) 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")) resp, err := http.Get(c.url("triggers/http"))
if err != nil { if err != nil {
return nil, err return nil, err
@@ -121,7 +121,7 @@ func (c *Client) HTTPTriggerList() ([]tpr.Httptrigger, error) {
return nil, err return nil, err
} }
triggers := make([]tpr.Httptrigger, 0) triggers := make([]crd.HTTPTrigger, 0)
err = json.Unmarshal(body, &triggers) err = json.Unmarshal(body, &triggers)
if err != nil { if err != nil {
return nil, err return nil, err
+10 -10
View File
@@ -22,13 +22,13 @@ import (
"fmt" "fmt"
"net/http" "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"
"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) reqbody, err := json.Marshal(w)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -45,7 +45,7 @@ func (c *Client) WatchCreate(w *tpr.Kuberneteswatchtrigger) (*api.ObjectMeta, er
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -54,7 +54,7 @@ func (c *Client) WatchCreate(w *tpr.Kuberneteswatchtrigger) (*api.ObjectMeta, er
return &m, nil 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("watches/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
@@ -69,7 +69,7 @@ func (c *Client) WatchGet(m *api.ObjectMeta) (*tpr.Kuberneteswatchtrigger, error
return nil, err return nil, err
} }
var w tpr.Kuberneteswatchtrigger var w crd.KubernetesWatchTrigger
err = json.Unmarshal(body, &w) err = json.Unmarshal(body, &w)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -78,18 +78,18 @@ func (c *Client) WatchGet(m *api.ObjectMeta) (*tpr.Kuberneteswatchtrigger, error
return &w, nil 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, return nil, fission.MakeError(fission.ErrorNotImplmented,
"watch update not implemented") "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("watches/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl) 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")) resp, err := http.Get(c.url("watches"))
if err != nil { if err != nil {
return nil, err return nil, err
@@ -101,7 +101,7 @@ func (c *Client) WatchList() ([]tpr.Kuberneteswatchtrigger, error) {
return nil, err return nil, err
} }
watches := make([]tpr.Kuberneteswatchtrigger, 0) watches := make([]crd.KubernetesWatchTrigger, 0)
err = json.Unmarshal(body, &watches) err = json.Unmarshal(body, &watches)
if err != nil { if err != nil {
return nil, err return nil, err
+11 -11
View File
@@ -22,12 +22,12 @@ import (
"fmt" "fmt"
"net/http" "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) reqbody, err := json.Marshal(t)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -44,7 +44,7 @@ func (c *Client) MessageQueueTriggerCreate(t *tpr.Messagequeuetrigger) (*api.Obj
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -53,7 +53,7 @@ func (c *Client) MessageQueueTriggerCreate(t *tpr.Messagequeuetrigger) (*api.Obj
return &m, nil 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("triggers/messagequeue/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
@@ -68,7 +68,7 @@ func (c *Client) MessageQueueTriggerGet(m *api.ObjectMeta) (*tpr.Messagequeuetri
return nil, err return nil, err
} }
var t tpr.Messagequeuetrigger var t crd.MessageQueueTrigger
err = json.Unmarshal(body, &t) err = json.Unmarshal(body, &t)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -77,7 +77,7 @@ func (c *Client) MessageQueueTriggerGet(m *api.ObjectMeta) (*tpr.Messagequeuetri
return &t, nil 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) reqbody, err := json.Marshal(mqTrigger)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -95,7 +95,7 @@ func (c *Client) MessageQueueTriggerUpdate(mqTrigger *tpr.Messagequeuetrigger) (
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -103,13 +103,13 @@ func (c *Client) MessageQueueTriggerUpdate(mqTrigger *tpr.Messagequeuetrigger) (
return &m, nil 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("triggers/messagequeue/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl) 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" relativeUrl := "triggers/messagequeue"
if len(mqType) > 0 { if len(mqType) > 0 {
// TODO remove this, replace with field selector // TODO remove this, replace with field selector
@@ -127,7 +127,7 @@ func (c *Client) MessageQueueTriggerList(mqType string) ([]tpr.Messagequeuetrigg
return nil, err return nil, err
} }
triggers := make([]tpr.Messagequeuetrigger, 0) triggers := make([]crd.MessageQueueTrigger, 0)
err = json.Unmarshal(body, &triggers) err = json.Unmarshal(body, &triggers)
if err != nil { if err != nil {
return nil, err return nil, err
+11 -11
View File
@@ -22,12 +22,12 @@ import (
"fmt" "fmt"
"net/http" "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) reqbody, err := json.Marshal(f)
if err != nil { if err != nil {
@@ -45,7 +45,7 @@ func (c *Client) PackageCreate(f *tpr.Package) (*api.ObjectMeta, error) {
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -54,7 +54,7 @@ func (c *Client) PackageCreate(f *tpr.Package) (*api.ObjectMeta, error) {
return &m, nil 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("packages/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
@@ -69,7 +69,7 @@ func (c *Client) PackageGet(m *api.ObjectMeta) (*tpr.Package, error) {
return nil, err return nil, err
} }
var f tpr.Package var f crd.Package
err = json.Unmarshal(body, &f) err = json.Unmarshal(body, &f)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -78,7 +78,7 @@ func (c *Client) PackageGet(m *api.ObjectMeta) (*tpr.Package, error) {
return &f, nil 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) reqbody, err := json.Marshal(f)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -96,7 +96,7 @@ func (c *Client) PackageUpdate(f *tpr.Package) (*api.ObjectMeta, error) {
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -104,13 +104,13 @@ func (c *Client) PackageUpdate(f *tpr.Package) (*api.ObjectMeta, error) {
return &m, nil 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("packages/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl) 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")) resp, err := http.Get(c.url("packages"))
if err != nil { if err != nil {
return nil, err return nil, err
@@ -122,7 +122,7 @@ func (c *Client) PackageList() ([]tpr.Package, error) {
return nil, err return nil, err
} }
funcs := make([]tpr.Package, 0) funcs := make([]crd.Package, 0)
err = json.Unmarshal(body, &funcs) err = json.Unmarshal(body, &funcs)
if err != nil { if err != nil {
return nil, err return nil, err
+11 -11
View File
@@ -22,12 +22,12 @@ import (
"fmt" "fmt"
"net/http" "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) reqbody, err := json.Marshal(t)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -44,7 +44,7 @@ func (c *Client) TimeTriggerCreate(t *tpr.Timetrigger) (*api.ObjectMeta, error)
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -53,7 +53,7 @@ func (c *Client) TimeTriggerCreate(t *tpr.Timetrigger) (*api.ObjectMeta, error)
return &m, nil 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("triggers/time/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
@@ -68,7 +68,7 @@ func (c *Client) TimeTriggerGet(m *api.ObjectMeta) (*tpr.Timetrigger, error) {
return nil, err return nil, err
} }
var t tpr.Timetrigger var t crd.TimeTrigger
err = json.Unmarshal(body, &t) err = json.Unmarshal(body, &t)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -77,7 +77,7 @@ func (c *Client) TimeTriggerGet(m *api.ObjectMeta) (*tpr.Timetrigger, error) {
return &t, nil 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) reqbody, err := json.Marshal(t)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -95,7 +95,7 @@ func (c *Client) TimeTriggerUpdate(t *tpr.Timetrigger) (*api.ObjectMeta, error)
return nil, err return nil, err
} }
var m api.ObjectMeta var m metav1.ObjectMeta
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -103,13 +103,13 @@ func (c *Client) TimeTriggerUpdate(t *tpr.Timetrigger) (*api.ObjectMeta, error)
return &m, nil 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("triggers/time/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl) 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")) resp, err := http.Get(c.url("triggers/time"))
if err != nil { if err != nil {
return nil, err return nil, err
@@ -121,7 +121,7 @@ func (c *Client) TimeTriggerList() ([]tpr.Timetrigger, error) {
return nil, err return nil, err
} }
triggers := make([]tpr.Timetrigger, 0) triggers := make([]crd.TimeTrigger, 0)
err = json.Unmarshal(body, &triggers) err = json.Unmarshal(body, &triggers)
if err != nil { if err != nil {
return nil, err return nil, err
+5 -5
View File
@@ -19,21 +19,21 @@ package controller
import ( import (
"log" "log"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func Start(port int) { func Start(port int) {
fc, kc, err := tpr.MakeFissionClient() fc, _, apiExtClient, err := crd.MakeFissionClient()
if err != nil { if err != nil {
log.Fatalf("Failed to connect to K8s API: %v", err) log.Fatalf("Failed to connect to K8s API: %v", err)
} }
err = tpr.EnsureFissionTPRs(kc) err = crd.EnsureFissionCRDs(apiExtClient)
if err != nil { 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() api, err := MakeAPI()
if err != nil { if err != nil {
+4 -4
View File
@@ -20,15 +20,15 @@ import (
"errors" "errors"
"regexp" "regexp"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func makeTPRBackedAPI() (*API, error) { func makeCRDBackedAPI() (*API, error) {
fissionClient, _, err := tpr.MakeFissionClient() fissionClient, kubernetesClient, _, err := crd.MakeFissionClient()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &API{fissionClient: fissionClient}, nil return &API{fissionClient: fissionClient, kubernetesClient: kubernetesClient}, nil
} }
func validateResourceName(name string) error { func validateResourceName(name string) error {
+8 -8
View File
@@ -23,14 +23,14 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
log "github.com/sirupsen/logrus" 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"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func (a *API) EnvironmentApiList(w http.ResponseWriter, r *http.Request) { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -52,7 +52,7 @@ func (a *API) EnvironmentApiCreate(w http.ResponseWriter, r *http.Request) {
return return
} }
var env tpr.Environment var env crd.Environment
err = json.Unmarshal(body, &env) err = json.Unmarshal(body, &env)
if err != nil { if err != nil {
log.Printf("Failed to unmarshal request body: [%v]", body) 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"] name := vars["environment"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { if len(ns) == 0 {
ns = api.NamespaceDefault ns = metav1.NamespaceDefault
} }
env, err := a.fissionClient.Environments(ns).Get(name) env, err := a.fissionClient.Environments(ns).Get(name)
@@ -115,7 +115,7 @@ func (a *API) EnvironmentApiUpdate(w http.ResponseWriter, r *http.Request) {
return return
} }
var env tpr.Environment var env crd.Environment
err = json.Unmarshal(body, &env) err = json.Unmarshal(body, &env)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -148,10 +148,10 @@ func (a *API) EnvironmentApiDelete(w http.ResponseWriter, r *http.Request) {
name := vars["environment"] name := vars["environment"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
+76 -8
View File
@@ -18,21 +18,27 @@ package controller
import ( import (
"encoding/json" "encoding/json"
"errors"
"io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"net/url" "net/url"
"sort"
"github.com/gorilla/mux" "github.com/gorilla/mux"
log "github.com/sirupsen/logrus" 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"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func (a *API) FunctionApiList(w http.ResponseWriter, r *http.Request) { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -54,7 +60,7 @@ func (a *API) FunctionApiCreate(w http.ResponseWriter, r *http.Request) {
return return
} }
var f tpr.Function var f crd.Function
err = json.Unmarshal(body, &f) err = json.Unmarshal(body, &f)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -88,7 +94,7 @@ func (a *API) FunctionApiGet(w http.ResponseWriter, r *http.Request) {
name := vars["function"] name := vars["function"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { if len(ns) == 0 {
ns = api.NamespaceDefault ns = metav1.NamespaceDefault
} }
f, err := a.fissionClient.Functions(ns).Get(name) f, err := a.fissionClient.Functions(ns).Get(name)
@@ -115,7 +121,7 @@ func (a *API) FunctionApiUpdate(w http.ResponseWriter, r *http.Request) {
return return
} }
var f tpr.Function var f crd.Function
err = json.Unmarshal(body, &f) err = json.Unmarshal(body, &f)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -147,10 +153,10 @@ func (a *API) FunctionApiDelete(w http.ResponseWriter, r *http.Request) {
name := vars["function"] name := vars["function"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -188,3 +194,65 @@ func (a *API) FunctionLogsApiPost(w http.ResponseWriter, r *http.Request) {
} }
proxy.ServeHTTP(w, r) 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
}
+15 -15
View File
@@ -23,14 +23,14 @@ import (
"net/http" "net/http"
"github.com/gorilla/mux" "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"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func (a *API) HTTPTriggerApiList(w http.ResponseWriter, r *http.Request) { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -45,8 +45,8 @@ func (a *API) HTTPTriggerApiList(w http.ResponseWriter, r *http.Request) {
a.respondWithSuccess(w, resp) a.respondWithSuccess(w, resp)
} }
func (a *API) checkHttpTriggerDuplicates(t *tpr.Httptrigger) error { func (a *API) checkHTTPTriggerDuplicates(t *crd.HTTPTrigger) error {
triggers, err := a.fissionClient.Httptriggers(api.NamespaceAll).List(api.ListOptions{}) triggers, err := a.fissionClient.HTTPTriggers(metav1.NamespaceAll).List(metav1.ListOptions{})
if err != nil { if err != nil {
return err return err
} }
@@ -67,7 +67,7 @@ func (a *API) HTTPTriggerApiCreate(w http.ResponseWriter, r *http.Request) {
return return
} }
var t tpr.Httptrigger var t crd.HTTPTrigger
err = json.Unmarshal(body, &t) err = json.Unmarshal(body, &t)
if err != nil { if err != nil {
a.respondWithError(w, err) 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) // 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
} }
tnew, err := a.fissionClient.Httptriggers(t.Metadata.Namespace).Create(&t) tnew, err := a.fissionClient.HTTPTriggers(t.Metadata.Namespace).Create(&t)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -108,10 +108,10 @@ func (a *API) HTTPTriggerApiGet(w http.ResponseWriter, r *http.Request) {
name := vars["httpTrigger"] name := vars["httpTrigger"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -136,7 +136,7 @@ func (a *API) HTTPTriggerApiUpdate(w http.ResponseWriter, r *http.Request) {
return return
} }
var t tpr.Httptrigger var t crd.HTTPTrigger
err = json.Unmarshal(body, &t) err = json.Unmarshal(body, &t)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -149,13 +149,13 @@ func (a *API) HTTPTriggerApiUpdate(w http.ResponseWriter, r *http.Request) {
return return
} }
err = a.checkHttpTriggerDuplicates(&t) err = a.checkHTTPTriggerDuplicates(&t)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
} }
tnew, err := a.fissionClient.Httptriggers(t.Metadata.Namespace).Update(&t) tnew, err := a.fissionClient.HTTPTriggers(t.Metadata.Namespace).Update(&t)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -174,10 +174,10 @@ func (a *API) HTTPTriggerApiDelete(w http.ResponseWriter, r *http.Request) {
name := vars["httpTrigger"] name := vars["httpTrigger"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
+11 -11
View File
@@ -22,15 +22,15 @@ import (
"net/http" "net/http"
"github.com/gorilla/mux" "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"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func (a *API) MessageQueueTriggerApiList(w http.ResponseWriter, r *http.Request) { func (a *API) MessageQueueTriggerApiList(w http.ResponseWriter, r *http.Request) {
//mqType := r.FormValue("mqtype") // ignored for now //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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -50,7 +50,7 @@ func (a *API) MessageQueueTriggerApiCreate(w http.ResponseWriter, r *http.Reques
return return
} }
var mqTrigger tpr.Messagequeuetrigger var mqTrigger crd.MessageQueueTrigger
err = json.Unmarshal(body, &mqTrigger) err = json.Unmarshal(body, &mqTrigger)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -63,7 +63,7 @@ func (a *API) MessageQueueTriggerApiCreate(w http.ResponseWriter, r *http.Reques
return return
} }
tnew, err := a.fissionClient.Messagequeuetriggers(mqTrigger.Metadata.Namespace).Create(&mqTrigger) tnew, err := a.fissionClient.MessageQueueTriggers(mqTrigger.Metadata.Namespace).Create(&mqTrigger)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -83,10 +83,10 @@ func (a *API) MessageQueueTriggerApiGet(w http.ResponseWriter, r *http.Request)
name := vars["mqTrigger"] name := vars["mqTrigger"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -109,7 +109,7 @@ func (a *API) MessageQueueTriggerApiUpdate(w http.ResponseWriter, r *http.Reques
return return
} }
var mqTrigger tpr.Messagequeuetrigger var mqTrigger crd.MessageQueueTrigger
err = json.Unmarshal(body, &mqTrigger) err = json.Unmarshal(body, &mqTrigger)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -122,7 +122,7 @@ func (a *API) MessageQueueTriggerApiUpdate(w http.ResponseWriter, r *http.Reques
return return
} }
tnew, err := a.fissionClient.Messagequeuetriggers(mqTrigger.Metadata.Namespace).Update(&mqTrigger) tnew, err := a.fissionClient.MessageQueueTriggers(mqTrigger.Metadata.Namespace).Update(&mqTrigger)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -141,10 +141,10 @@ func (a *API) MessageQueueTriggerApiDelete(w http.ResponseWriter, r *http.Reques
name := vars["mqTrigger"] name := vars["mqTrigger"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
+8 -8
View File
@@ -22,14 +22,14 @@ import (
"net/http" "net/http"
"github.com/gorilla/mux" "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"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func (a *API) PackageApiList(w http.ResponseWriter, r *http.Request) { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -51,7 +51,7 @@ func (a *API) PackageApiCreate(w http.ResponseWriter, r *http.Request) {
return return
} }
var f tpr.Package var f crd.Package
err = json.Unmarshal(body, &f) err = json.Unmarshal(body, &f)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -97,7 +97,7 @@ func (a *API) PackageApiGet(w http.ResponseWriter, r *http.Request) {
name := vars["package"] name := vars["package"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { if len(ns) == 0 {
ns = api.NamespaceDefault ns = metav1.NamespaceDefault
} }
raw := r.FormValue("raw") // just the deployment pkg raw := r.FormValue("raw") // just the deployment pkg
@@ -130,7 +130,7 @@ func (a *API) PackageApiUpdate(w http.ResponseWriter, r *http.Request) {
return return
} }
var f tpr.Package var f crd.Package
err = json.Unmarshal(body, &f) err = json.Unmarshal(body, &f)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -162,10 +162,10 @@ func (a *API) PackageApiDelete(w http.ResponseWriter, r *http.Request) {
name := vars["package"] name := vars["package"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
+11 -11
View File
@@ -23,14 +23,14 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/robfig/cron" "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"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func (a *API) TimeTriggerApiList(w http.ResponseWriter, r *http.Request) { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -52,7 +52,7 @@ func (a *API) TimeTriggerApiCreate(w http.ResponseWriter, r *http.Request) {
return return
} }
var t tpr.Timetrigger var t crd.TimeTrigger
err = json.Unmarshal(body, &t) err = json.Unmarshal(body, &t)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -73,7 +73,7 @@ func (a *API) TimeTriggerApiCreate(w http.ResponseWriter, r *http.Request) {
return return
} }
tnew, err := a.fissionClient.Timetriggers(t.Metadata.Namespace).Create(&t) tnew, err := a.fissionClient.TimeTriggers(t.Metadata.Namespace).Create(&t)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -94,10 +94,10 @@ func (a *API) TimeTriggerApiGet(w http.ResponseWriter, r *http.Request) {
name := vars["timeTrigger"] name := vars["timeTrigger"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -122,7 +122,7 @@ func (a *API) TimeTriggerApiUpdate(w http.ResponseWriter, r *http.Request) {
return return
} }
var t tpr.Timetrigger var t crd.TimeTrigger
err = json.Unmarshal(body, &t) err = json.Unmarshal(body, &t)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -142,7 +142,7 @@ func (a *API) TimeTriggerApiUpdate(w http.ResponseWriter, r *http.Request) {
return return
} }
tnew, err := a.fissionClient.Timetriggers(t.Metadata.Namespace).Update(&t) tnew, err := a.fissionClient.TimeTriggers(t.Metadata.Namespace).Update(&t)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -161,10 +161,10 @@ func (a *API) TimeTriggerApiDelete(w http.ResponseWriter, r *http.Request) {
name := vars["timeTrigger"] name := vars["timeTrigger"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
+64
View File
@@ -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)
}
+9 -9
View File
@@ -22,14 +22,14 @@ import (
"net/http" "net/http"
"github.com/gorilla/mux" "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"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func (a *API) WatchApiList(w http.ResponseWriter, r *http.Request) { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -51,7 +51,7 @@ func (a *API) WatchApiCreate(w http.ResponseWriter, r *http.Request) {
return return
} }
var watch tpr.Kuberneteswatchtrigger var watch crd.KubernetesWatchTrigger
err = json.Unmarshal(body, &watch) err = json.Unmarshal(body, &watch)
if err != nil { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
@@ -66,7 +66,7 @@ func (a *API) WatchApiCreate(w http.ResponseWriter, r *http.Request) {
// TODO check for duplicate watches // 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -87,10 +87,10 @@ func (a *API) WatchApiGet(w http.ResponseWriter, r *http.Request) {
name := vars["watch"] name := vars["watch"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
@@ -115,10 +115,10 @@ func (a *API) WatchApiDelete(w http.ResponseWriter, r *http.Request) {
name := vars["watch"] name := vars["watch"]
ns := vars["namespace"] ns := vars["namespace"]
if len(ns) == 0 { 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 { if err != nil {
a.respondWithError(w, err) a.respondWithError(w, err)
return return
+220
View File
@@ -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
View File
@@ -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
}
+69 -58
View File
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tpr package crd
import ( import (
"log" "log"
@@ -22,9 +22,8 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/api/unversioned" "k8s.io/client-go/rest"
"k8s.io/client-go/1.5/rest"
"github.com/fission/fission" "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 // sample function object
function := &Function{ function := &Function{
TypeMeta: unversioned.TypeMeta{ TypeMeta: metav1.TypeMeta{
Kind: "Function", Kind: "Function",
APIVersion: "fission.io/v1", APIVersion: "fission.io/v1",
}, },
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: "hello", Name: "hello",
Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.FunctionSpec{ Spec: fission.FunctionSpec{
Package: fission.FunctionPackageRef{ Package: fission.FunctionPackageRef{
@@ -60,7 +60,7 @@ func functionTests(tprClient *rest.RESTClient) {
} }
// Test function CRUD // Test function CRUD
fi := MakeFunctionInterface(tprClient, api.NamespaceDefault) fi := MakeFunctionInterface(crdClient, metav1.NamespaceDefault)
// cleanup from old crashed tests, ignore errors // cleanup from old crashed tests, ignore errors
fi.Delete(function.Metadata.Name, nil) fi.Delete(function.Metadata.Name, nil)
@@ -82,6 +82,7 @@ func functionTests(tprClient *rest.RESTClient) {
log.Printf("f.Metadata = %#v", f.Metadata) log.Printf("f.Metadata = %#v", f.Metadata)
// update // update
function.Metadata.ResourceVersion = f.Metadata.ResourceVersion
function.Spec.Environment.Name = "yyy" function.Spec.Environment.Name = "yyy"
f, err = fi.Update(function) f, err = fi.Update(function)
panicIf(err) panicIf(err)
@@ -89,12 +90,12 @@ func functionTests(tprClient *rest.RESTClient) {
log.Printf("f.Metadata = %#v", f.Metadata) log.Printf("f.Metadata = %#v", f.Metadata)
// list // list
fl, err := fi.List(api.ListOptions{}) fl, err := fi.List(metav1.ListOptions{})
panicIf(err) panicIf(err)
if len(fl.Items) != 1 { 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]) log.Panicf("bad object from list: %v", fl.Items[0])
} }
@@ -103,10 +104,11 @@ func functionTests(tprClient *rest.RESTClient) {
panicIf(err) panicIf(err)
// start a watch // start a watch
wi, err := fi.Watch(api.ListOptions{}) wi, err := fi.Watch(metav1.ListOptions{})
panicIf(err) panicIf(err)
start := time.Now() start := time.Now()
function.Metadata.ResourceVersion = ""
f, err = fi.Create(function) f, err = fi.Create(function)
panicIf(err) panicIf(err)
defer fi.Delete(f.Metadata.Name, nil) 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 // sample environment object
environment := &Environment{ environment := &Environment{
TypeMeta: unversioned.TypeMeta{ TypeMeta: metav1.TypeMeta{
Kind: "Environment", Kind: "Environment",
APIVersion: "fission.io/v1", APIVersion: "fission.io/v1",
}, },
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: "hello", Name: "hello",
Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.EnvironmentSpec{ Spec: fission.EnvironmentSpec{
Runtime: fission.Runtime{ Runtime: fission.Runtime{
@@ -154,7 +157,7 @@ func environmentTests(tprClient *rest.RESTClient) {
} }
// Test environment CRUD // Test environment CRUD
ei := MakeEnvironmentInterface(tprClient, api.NamespaceDefault) ei := MakeEnvironmentInterface(crdClient, metav1.NamespaceDefault)
// cleanup from old crashed tests, ignore errors // cleanup from old crashed tests, ignore errors
ei.Delete(environment.Metadata.Name, nil) ei.Delete(environment.Metadata.Name, nil)
@@ -174,17 +177,18 @@ func environmentTests(tprClient *rest.RESTClient) {
} }
// update // update
environment.Metadata.ResourceVersion = e.Metadata.ResourceVersion
environment.Spec.Runtime.Image = "www" environment.Spec.Runtime.Image = "www"
e, err = ei.Update(environment) e, err = ei.Update(environment)
panicIf(err) panicIf(err)
// list // list
el, err := ei.List(api.ListOptions{}) el, err := ei.List(metav1.ListOptions{})
panicIf(err) panicIf(err)
if len(el.Items) != 1 { 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]) log.Panicf("bad object from list: %v", el.Items[0])
} }
@@ -193,10 +197,11 @@ func environmentTests(tprClient *rest.RESTClient) {
panicIf(err) panicIf(err)
// start a watch // start a watch
wi, err := ei.Watch(api.ListOptions{}) wi, err := ei.Watch(metav1.ListOptions{})
panicIf(err) panicIf(err)
start := time.Now() start := time.Now()
environment.Metadata.ResourceVersion = ""
e, err = ei.Create(environment) e, err = ei.Create(environment)
panicIf(err) panicIf(err)
defer ei.Delete(e.Metadata.Name, nil) 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 // sample httpTrigger object
httpTrigger := &Httptrigger{ httpTrigger := &HTTPTrigger{
TypeMeta: unversioned.TypeMeta{ TypeMeta: metav1.TypeMeta{
Kind: "Httptrigger", Kind: "HTTPTrigger",
APIVersion: "fission.io/v1", APIVersion: "fission.io/v1",
}, },
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: "hello", Name: "hello",
Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.HTTPTriggerSpec{ Spec: fission.HTTPTriggerSpec{
RelativeURL: "/hi", RelativeURL: "/hi",
@@ -243,7 +249,7 @@ func httpTriggerTests(tprClient *rest.RESTClient) {
} }
// Test httpTrigger CRUD // Test httpTrigger CRUD
ei := MakeHttptriggerInterface(tprClient, api.NamespaceDefault) ei := MakeHTTPTriggerInterface(crdClient, metav1.NamespaceDefault)
// cleanup from old crashed tests, ignore errors // cleanup from old crashed tests, ignore errors
ei.Delete(httpTrigger.Metadata.Name, nil) ei.Delete(httpTrigger.Metadata.Name, nil)
@@ -263,17 +269,18 @@ func httpTriggerTests(tprClient *rest.RESTClient) {
} }
// update // update
httpTrigger.Metadata.ResourceVersion = e.Metadata.ResourceVersion
httpTrigger.Spec.Method = "POST" httpTrigger.Spec.Method = "POST"
e, err = ei.Update(httpTrigger) e, err = ei.Update(httpTrigger)
panicIf(err) panicIf(err)
// list // list
el, err := ei.List(api.ListOptions{}) el, err := ei.List(metav1.ListOptions{})
panicIf(err) panicIf(err)
if len(el.Items) != 1 { 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]) log.Panicf("bad object from list: %v", el.Items[0])
} }
@@ -282,10 +289,11 @@ func httpTriggerTests(tprClient *rest.RESTClient) {
panicIf(err) panicIf(err)
// start a watch // start a watch
wi, err := ei.Watch(api.ListOptions{}) wi, err := ei.Watch(metav1.ListOptions{})
panicIf(err) panicIf(err)
start := time.Now() start := time.Now()
httpTrigger.Metadata.ResourceVersion = ""
e, err = ei.Create(httpTrigger) e, err = ei.Create(httpTrigger)
panicIf(err) panicIf(err)
defer ei.Delete(e.Metadata.Name, nil) defer ei.Delete(e.Metadata.Name, nil)
@@ -298,9 +306,9 @@ func httpTriggerTests(tprClient *rest.RESTClient) {
log.Panicf("Didn't get watch event") log.Panicf("Didn't get watch event")
} }
case ev := <-wi.ResultChan(): case ev := <-wi.ResultChan():
obj, ok := ev.Object.(*Httptrigger) obj, ok := ev.Object.(*HTTPTrigger)
if !ok { if !ok {
log.Panicf("Can't cast to Httptrigger") log.Panicf("Can't cast to HTTPTrigger")
} }
if obj.Spec.Method != httpTrigger.Spec.Method { if obj.Spec.Method != httpTrigger.Spec.Method {
log.Panicf("Bad object from watch: %#v", obj) 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 // sample kubernetesWatchTrigger object
kubernetesWatchTrigger := &Kuberneteswatchtrigger{ kubernetesWatchTrigger := &KubernetesWatchTrigger{
TypeMeta: unversioned.TypeMeta{ TypeMeta: metav1.TypeMeta{
Kind: "Kuberneteswatchtrigger", Kind: "KubernetesWatchTrigger",
APIVersion: "fission.io/v1", APIVersion: "fission.io/v1",
}, },
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: "hello", Name: "hello",
Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.KubernetesWatchTriggerSpec{ Spec: fission.KubernetesWatchTriggerSpec{
Namespace: "foo", Namespace: "foo",
@@ -335,7 +344,7 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) {
} }
// Test kubernetesWatchTrigger CRUD // Test kubernetesWatchTrigger CRUD
ei := MakeKuberneteswatchtriggerInterface(tprClient, api.NamespaceDefault) ei := MakeKubernetesWatchTriggerInterface(crdClient, metav1.NamespaceDefault)
// cleanup from old crashed tests, ignore errors // cleanup from old crashed tests, ignore errors
ei.Delete(kubernetesWatchTrigger.Metadata.Name, nil) ei.Delete(kubernetesWatchTrigger.Metadata.Name, nil)
@@ -355,17 +364,18 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) {
} }
// update // update
kubernetesWatchTrigger.Metadata.ResourceVersion = e.Metadata.ResourceVersion
kubernetesWatchTrigger.Spec.Type = "service" kubernetesWatchTrigger.Spec.Type = "service"
e, err = ei.Update(kubernetesWatchTrigger) e, err = ei.Update(kubernetesWatchTrigger)
panicIf(err) panicIf(err)
// list // list
el, err := ei.List(api.ListOptions{}) el, err := ei.List(metav1.ListOptions{})
panicIf(err) panicIf(err)
if len(el.Items) != 1 { 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]) log.Panicf("bad object from list: %v", el.Items[0])
} }
@@ -374,10 +384,11 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) {
panicIf(err) panicIf(err)
// start a watch // start a watch
wi, err := ei.Watch(api.ListOptions{}) wi, err := ei.Watch(metav1.ListOptions{})
panicIf(err) panicIf(err)
start := time.Now() start := time.Now()
kubernetesWatchTrigger.Metadata.ResourceVersion = ""
e, err = ei.Create(kubernetesWatchTrigger) e, err = ei.Create(kubernetesWatchTrigger)
panicIf(err) panicIf(err)
defer ei.Delete(e.Metadata.Name, nil) defer ei.Delete(e.Metadata.Name, nil)
@@ -390,9 +401,9 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) {
log.Panicf("Didn't get watch event") log.Panicf("Didn't get watch event")
} }
case ev := <-wi.ResultChan(): case ev := <-wi.ResultChan():
obj, ok := ev.Object.(*Kuberneteswatchtrigger) obj, ok := ev.Object.(*KubernetesWatchTrigger)
if !ok { if !ok {
log.Panicf("Can't cast to Kuberneteswatchtrigger") log.Panicf("Can't cast to KubernetesWatchTrigger")
} }
if obj.Spec.Type != kubernetesWatchTrigger.Spec.Type { if obj.Spec.Type != kubernetesWatchTrigger.Spec.Type {
log.Panicf("Bad object from watch: %#v", obj) 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 // skip test if no cluster available for testing
kubeconfig := os.Getenv("KUBECONFIG") kubeconfig := os.Getenv("KUBECONFIG")
if len(kubeconfig) == 0 { if len(kubeconfig) == 0 {
@@ -413,22 +424,22 @@ func TestTpr(t *testing.T) {
// Create the client config. Needs the KUBECONFIG env var to // Create the client config. Needs the KUBECONFIG env var to
// point at a valid kubeconfig. // point at a valid kubeconfig.
config, clientset, err := GetKubernetesClient() config, _, apiExtClient, err := GetKubernetesClient()
panicIf(err) panicIf(err)
// init our types // init our types
err = EnsureFissionTPRs(clientset) err = EnsureFissionCRDs(apiExtClient)
panicIf(err) panicIf(err)
// rest client with knowledge about our tpr types // rest client with knowledge about our crd types
tprClient, err := GetTprClient(config) crdClient, err := GetCrdClient(config)
panicIf(err) panicIf(err)
err = waitForTPRs(tprClient) err = waitForCRDs(crdClient)
panicIf(err) panicIf(err)
functionTests(tprClient) functionTests(crdClient)
environmentTests(tprClient) environmentTests(crdClient)
httpTriggerTests(tprClient) httpTriggerTests(crdClient)
kubernetesWatchTriggerTests(tprClient) kubernetesWatchTriggerTests(crdClient)
} }
+15 -14
View File
@@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tpr package crd
import ( import (
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/1.5/rest" "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
) )
type ( type (
@@ -27,9 +28,9 @@ type (
Create(*Environment) (*Environment, error) Create(*Environment) (*Environment, error)
Get(name string) (*Environment, error) Get(name string) (*Environment, error)
Update(*Environment) (*Environment, error) Update(*Environment) (*Environment, error)
Delete(name string, options *api.DeleteOptions) error Delete(name string, options *metav1.DeleteOptions) error
List(opts api.ListOptions) (*EnvironmentList, error) List(opts metav1.ListOptions) (*EnvironmentList, error)
Watch(opts api.ListOptions) (watch.Interface, error) Watch(opts metav1.ListOptions) (watch.Interface, error)
} }
environmentClient struct { 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{ return &environmentClient{
client: tprClient, client: crdClient,
namespace: namespace, namespace: namespace,
} }
} }
@@ -85,7 +86,7 @@ func (ec *environmentClient) Update(e *Environment) (*Environment, error) {
return &result, nil 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(). return ec.client.Delete().
Namespace(ec.namespace). Namespace(ec.namespace).
Resource("environments"). Resource("environments").
@@ -95,12 +96,12 @@ func (ec *environmentClient) Delete(name string, opts *api.DeleteOptions) error
Error() Error()
} }
func (ec *environmentClient) List(opts api.ListOptions) (*EnvironmentList, error) { func (ec *environmentClient) List(opts metav1.ListOptions) (*EnvironmentList, error) {
var result EnvironmentList var result EnvironmentList
err := ec.client.Get(). err := ec.client.Get().
Namespace(ec.namespace). Namespace(ec.namespace).
Resource("environments"). Resource("environments").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Do(). Do().
Into(&result) Into(&result)
if err != nil { if err != nil {
@@ -109,11 +110,11 @@ func (ec *environmentClient) List(opts api.ListOptions) (*EnvironmentList, error
return &result, nil 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(). return ec.client.Get().
Prefix("watch"). Prefix("watch").
Namespace(ec.namespace). Namespace(ec.namespace).
Resource("environments"). Resource("environments").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Watch() Watch()
} }
+15 -14
View File
@@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tpr package crd
import ( import (
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/1.5/rest" "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
) )
type ( type (
@@ -27,9 +28,9 @@ type (
Create(*Function) (*Function, error) Create(*Function) (*Function, error)
Get(name string) (*Function, error) Get(name string) (*Function, error)
Update(*Function) (*Function, error) Update(*Function) (*Function, error)
Delete(name string, options *api.DeleteOptions) error Delete(name string, options *metav1.DeleteOptions) error
List(opts api.ListOptions) (*FunctionList, error) List(opts metav1.ListOptions) (*FunctionList, error)
Watch(opts api.ListOptions) (watch.Interface, error) Watch(opts metav1.ListOptions) (watch.Interface, error)
} }
functionClient struct { 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{ return &functionClient{
client: tprClient, client: crdClient,
namespace: namespace, namespace: namespace,
} }
} }
@@ -85,7 +86,7 @@ func (fc *functionClient) Update(f *Function) (*Function, error) {
return &result, nil 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(). return fc.client.Delete().
Namespace(fc.namespace). Namespace(fc.namespace).
Resource("functions"). Resource("functions").
@@ -95,12 +96,12 @@ func (fc *functionClient) Delete(name string, opts *api.DeleteOptions) error {
Error() Error()
} }
func (fc *functionClient) List(opts api.ListOptions) (*FunctionList, error) { func (fc *functionClient) List(opts metav1.ListOptions) (*FunctionList, error) {
var result FunctionList var result FunctionList
err := fc.client.Get(). err := fc.client.Get().
Namespace(fc.namespace). Namespace(fc.namespace).
Resource("functions"). Resource("functions").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Do(). Do().
Into(&result) Into(&result)
if err != nil { if err != nil {
@@ -109,11 +110,11 @@ func (fc *functionClient) List(opts api.ListOptions) (*FunctionList, error) {
return &result, nil 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(). return fc.client.Get().
Prefix("watch"). Prefix("watch").
Namespace(fc.namespace). Namespace(fc.namespace).
Resource("functions"). Resource("functions").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Watch() Watch()
} }
+26 -25
View File
@@ -14,22 +14,23 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tpr package crd
import ( import (
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/1.5/rest" "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
) )
type ( type (
HttptriggerInterface interface { HTTPTriggerInterface interface {
Create(*Httptrigger) (*Httptrigger, error) Create(*HTTPTrigger) (*HTTPTrigger, error)
Get(name string) (*Httptrigger, error) Get(name string) (*HTTPTrigger, error)
Update(*Httptrigger) (*Httptrigger, error) Update(*HTTPTrigger) (*HTTPTrigger, error)
Delete(name string, options *api.DeleteOptions) error Delete(name string, options *metav1.DeleteOptions) error
List(opts api.ListOptions) (*HttptriggerList, error) List(opts metav1.ListOptions) (*HTTPTriggerList, error)
Watch(opts api.ListOptions) (watch.Interface, error) Watch(opts metav1.ListOptions) (watch.Interface, error)
} }
httpTriggerClient struct { 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{ return &httpTriggerClient{
client: tprClient, client: crdClient,
namespace: namespace, namespace: namespace,
} }
} }
func (c *httpTriggerClient) Create(obj *Httptrigger) (*Httptrigger, error) { func (c *httpTriggerClient) Create(obj *HTTPTrigger) (*HTTPTrigger, error) {
var result Httptrigger var result HTTPTrigger
err := c.client.Post(). err := c.client.Post().
Resource("httptriggers"). Resource("httptriggers").
Namespace(c.namespace). Namespace(c.namespace).
@@ -58,8 +59,8 @@ func (c *httpTriggerClient) Create(obj *Httptrigger) (*Httptrigger, error) {
return &result, nil return &result, nil
} }
func (c *httpTriggerClient) Get(name string) (*Httptrigger, error) { func (c *httpTriggerClient) Get(name string) (*HTTPTrigger, error) {
var result Httptrigger var result HTTPTrigger
err := c.client.Get(). err := c.client.Get().
Resource("httptriggers"). Resource("httptriggers").
Namespace(c.namespace). Namespace(c.namespace).
@@ -71,8 +72,8 @@ func (c *httpTriggerClient) Get(name string) (*Httptrigger, error) {
return &result, nil return &result, nil
} }
func (c *httpTriggerClient) Update(obj *Httptrigger) (*Httptrigger, error) { func (c *httpTriggerClient) Update(obj *HTTPTrigger) (*HTTPTrigger, error) {
var result Httptrigger var result HTTPTrigger
err := c.client.Put(). err := c.client.Put().
Resource("httptriggers"). Resource("httptriggers").
Namespace(c.namespace). Namespace(c.namespace).
@@ -85,7 +86,7 @@ func (c *httpTriggerClient) Update(obj *Httptrigger) (*Httptrigger, error) {
return &result, nil 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(). return c.client.Delete().
Namespace(c.namespace). Namespace(c.namespace).
Resource("httptriggers"). Resource("httptriggers").
@@ -95,12 +96,12 @@ func (c *httpTriggerClient) Delete(name string, opts *api.DeleteOptions) error {
Error() Error()
} }
func (c *httpTriggerClient) List(opts api.ListOptions) (*HttptriggerList, error) { func (c *httpTriggerClient) List(opts metav1.ListOptions) (*HTTPTriggerList, error) {
var result HttptriggerList var result HTTPTriggerList
err := c.client.Get(). err := c.client.Get().
Namespace(c.namespace). Namespace(c.namespace).
Resource("httptriggers"). Resource("httptriggers").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Do(). Do().
Into(&result) Into(&result)
if err != nil { if err != nil {
@@ -109,11 +110,11 @@ func (c *httpTriggerClient) List(opts api.ListOptions) (*HttptriggerList, error)
return &result, nil 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(). return c.client.Get().
Prefix("watch"). Prefix("watch").
Namespace(c.namespace). Namespace(c.namespace).
Resource("httptriggers"). Resource("httptriggers").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Watch() Watch()
} }
+3 -3
View File
@@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tpr package crd
import ( import (
"fmt" "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 // Given metadata, create a key that uniquely identifies the contents
@@ -28,6 +28,6 @@ import (
// content. (ResourceVersion may also update on status updates, so // content. (ResourceVersion may also update on status updates, so
// this will result in some unnecessary cache misses. That should be // this will result in some unnecessary cache misses. That should be
// ok.) // ok.)
func CacheKey(metadata *api.ObjectMeta) string { func CacheKey(metadata *metav1.ObjectMeta) string {
return fmt.Sprintf("%v_%v", metadata.UID, metadata.ResourceVersion) 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. limitations under the License.
*/ */
package tpr package crd
import ( import (
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/1.5/rest" "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
) )
type ( type (
KuberneteswatchtriggerInterface interface { KubernetesWatchTriggerInterface interface {
Create(*Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error) Create(*KubernetesWatchTrigger) (*KubernetesWatchTrigger, error)
Get(name string) (*Kuberneteswatchtrigger, error) Get(name string) (*KubernetesWatchTrigger, error)
Update(*Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error) Update(*KubernetesWatchTrigger) (*KubernetesWatchTrigger, error)
Delete(name string, options *api.DeleteOptions) error Delete(name string, options *metav1.DeleteOptions) error
List(opts api.ListOptions) (*KuberneteswatchtriggerList, error) List(opts metav1.ListOptions) (*KubernetesWatchTriggerList, error)
Watch(opts api.ListOptions) (watch.Interface, error) Watch(opts metav1.ListOptions) (watch.Interface, error)
} }
kubernetesWatchTriggerClient struct { 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{ return &kubernetesWatchTriggerClient{
client: tprClient, client: crdClient,
namespace: namespace, namespace: namespace,
} }
} }
func (c *kubernetesWatchTriggerClient) Create(obj *Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error) { func (c *kubernetesWatchTriggerClient) Create(obj *KubernetesWatchTrigger) (*KubernetesWatchTrigger, error) {
var result Kuberneteswatchtrigger var result KubernetesWatchTrigger
err := c.client.Post(). err := c.client.Post().
Resource("kuberneteswatchtriggers"). Resource("kuberneteswatchtriggers").
Namespace(c.namespace). Namespace(c.namespace).
@@ -58,8 +59,8 @@ func (c *kubernetesWatchTriggerClient) Create(obj *Kuberneteswatchtrigger) (*Kub
return &result, nil return &result, nil
} }
func (c *kubernetesWatchTriggerClient) Get(name string) (*Kuberneteswatchtrigger, error) { func (c *kubernetesWatchTriggerClient) Get(name string) (*KubernetesWatchTrigger, error) {
var result Kuberneteswatchtrigger var result KubernetesWatchTrigger
err := c.client.Get(). err := c.client.Get().
Resource("kuberneteswatchtriggers"). Resource("kuberneteswatchtriggers").
Namespace(c.namespace). Namespace(c.namespace).
@@ -71,8 +72,8 @@ func (c *kubernetesWatchTriggerClient) Get(name string) (*Kuberneteswatchtrigger
return &result, nil return &result, nil
} }
func (c *kubernetesWatchTriggerClient) Update(obj *Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error) { func (c *kubernetesWatchTriggerClient) Update(obj *KubernetesWatchTrigger) (*KubernetesWatchTrigger, error) {
var result Kuberneteswatchtrigger var result KubernetesWatchTrigger
err := c.client.Put(). err := c.client.Put().
Resource("kuberneteswatchtriggers"). Resource("kuberneteswatchtriggers").
Namespace(c.namespace). Namespace(c.namespace).
@@ -85,7 +86,7 @@ func (c *kubernetesWatchTriggerClient) Update(obj *Kuberneteswatchtrigger) (*Kub
return &result, nil 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(). return c.client.Delete().
Namespace(c.namespace). Namespace(c.namespace).
Resource("kuberneteswatchtriggers"). Resource("kuberneteswatchtriggers").
@@ -95,12 +96,12 @@ func (c *kubernetesWatchTriggerClient) Delete(name string, opts *api.DeleteOptio
Error() Error()
} }
func (c *kubernetesWatchTriggerClient) List(opts api.ListOptions) (*KuberneteswatchtriggerList, error) { func (c *kubernetesWatchTriggerClient) List(opts metav1.ListOptions) (*KubernetesWatchTriggerList, error) {
var result KuberneteswatchtriggerList var result KubernetesWatchTriggerList
err := c.client.Get(). err := c.client.Get().
Namespace(c.namespace). Namespace(c.namespace).
Resource("kuberneteswatchtriggers"). Resource("kuberneteswatchtriggers").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Do(). Do().
Into(&result) Into(&result)
if err != nil { if err != nil {
@@ -109,11 +110,11 @@ func (c *kubernetesWatchTriggerClient) List(opts api.ListOptions) (*Kuberneteswa
return &result, nil 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(). return c.client.Get().
Prefix("watch"). Prefix("watch").
Namespace(c.namespace). Namespace(c.namespace).
Resource("kuberneteswatchtriggers"). Resource("kuberneteswatchtriggers").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Watch() Watch()
} }
@@ -14,39 +14,40 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tpr package crd
import ( import (
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/1.5/rest" "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
) )
type ( type (
MessagequeuetriggerInterface interface { MessageQueueTriggerInterface interface {
Create(*Messagequeuetrigger) (*Messagequeuetrigger, error) Create(*MessageQueueTrigger) (*MessageQueueTrigger, error)
Get(name string) (*Messagequeuetrigger, error) Get(name string) (*MessageQueueTrigger, error)
Update(*Messagequeuetrigger) (*Messagequeuetrigger, error) Update(*MessageQueueTrigger) (*MessageQueueTrigger, error)
Delete(name string, options *api.DeleteOptions) error Delete(name string, options *metav1.DeleteOptions) error
List(opts api.ListOptions) (*MessagequeuetriggerList, error) List(opts metav1.ListOptions) (*MessageQueueTriggerList, error)
Watch(opts api.ListOptions) (watch.Interface, error) Watch(opts metav1.ListOptions) (watch.Interface, error)
} }
messagequeuetriggerClient struct { messageQueueTriggerClient struct {
client *rest.RESTClient client *rest.RESTClient
namespace string namespace string
} }
) )
func MakeMessagequeuetriggerInterface(tprClient *rest.RESTClient, namespace string) MessagequeuetriggerInterface { func MakeMessageQueueTriggerInterface(crdClient *rest.RESTClient, namespace string) MessageQueueTriggerInterface {
return &messagequeuetriggerClient{ return &messageQueueTriggerClient{
client: tprClient, client: crdClient,
namespace: namespace, namespace: namespace,
} }
} }
func (fc *messagequeuetriggerClient) Create(f *Messagequeuetrigger) (*Messagequeuetrigger, error) { func (fc *messageQueueTriggerClient) Create(f *MessageQueueTrigger) (*MessageQueueTrigger, error) {
var result Messagequeuetrigger var result MessageQueueTrigger
err := fc.client.Post(). err := fc.client.Post().
Resource("messagequeuetriggers"). Resource("messagequeuetriggers").
Namespace(fc.namespace). Namespace(fc.namespace).
@@ -58,8 +59,8 @@ func (fc *messagequeuetriggerClient) Create(f *Messagequeuetrigger) (*Messageque
return &result, nil return &result, nil
} }
func (fc *messagequeuetriggerClient) Get(name string) (*Messagequeuetrigger, error) { func (fc *messageQueueTriggerClient) Get(name string) (*MessageQueueTrigger, error) {
var result Messagequeuetrigger var result MessageQueueTrigger
err := fc.client.Get(). err := fc.client.Get().
Resource("messagequeuetriggers"). Resource("messagequeuetriggers").
Namespace(fc.namespace). Namespace(fc.namespace).
@@ -71,8 +72,8 @@ func (fc *messagequeuetriggerClient) Get(name string) (*Messagequeuetrigger, err
return &result, nil return &result, nil
} }
func (fc *messagequeuetriggerClient) Update(f *Messagequeuetrigger) (*Messagequeuetrigger, error) { func (fc *messageQueueTriggerClient) Update(f *MessageQueueTrigger) (*MessageQueueTrigger, error) {
var result Messagequeuetrigger var result MessageQueueTrigger
err := fc.client.Put(). err := fc.client.Put().
Resource("messagequeuetriggers"). Resource("messagequeuetriggers").
Namespace(fc.namespace). Namespace(fc.namespace).
@@ -85,7 +86,7 @@ func (fc *messagequeuetriggerClient) Update(f *Messagequeuetrigger) (*Messageque
return &result, nil 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(). return fc.client.Delete().
Namespace(fc.namespace). Namespace(fc.namespace).
Resource("messagequeuetriggers"). Resource("messagequeuetriggers").
@@ -95,12 +96,12 @@ func (fc *messagequeuetriggerClient) Delete(name string, opts *api.DeleteOptions
Error() Error()
} }
func (fc *messagequeuetriggerClient) List(opts api.ListOptions) (*MessagequeuetriggerList, error) { func (fc *messageQueueTriggerClient) List(opts metav1.ListOptions) (*MessageQueueTriggerList, error) {
var result MessagequeuetriggerList var result MessageQueueTriggerList
err := fc.client.Get(). err := fc.client.Get().
Namespace(fc.namespace). Namespace(fc.namespace).
Resource("messagequeuetriggers"). Resource("messagequeuetriggers").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Do(). Do().
Into(&result) Into(&result)
if err != nil { if err != nil {
@@ -109,11 +110,11 @@ func (fc *messagequeuetriggerClient) List(opts api.ListOptions) (*Messagequeuetr
return &result, nil 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(). return fc.client.Get().
Prefix("watch"). Prefix("watch").
Namespace(fc.namespace). Namespace(fc.namespace).
Resource("messagequeuetriggers"). Resource("messagequeuetriggers").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Watch() Watch()
} }
+15 -14
View File
@@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tpr package crd
import ( import (
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/1.5/rest" "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
) )
type ( type (
@@ -27,9 +28,9 @@ type (
Create(*Package) (*Package, error) Create(*Package) (*Package, error)
Get(name string) (*Package, error) Get(name string) (*Package, error)
Update(*Package) (*Package, error) Update(*Package) (*Package, error)
Delete(name string, options *api.DeleteOptions) error Delete(name string, options *metav1.DeleteOptions) error
List(opts api.ListOptions) (*PackageList, error) List(opts metav1.ListOptions) (*PackageList, error)
Watch(opts api.ListOptions) (watch.Interface, error) Watch(opts metav1.ListOptions) (watch.Interface, error)
} }
packageClient struct { 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{ return &packageClient{
client: tprClient, client: crdClient,
namespace: namespace, namespace: namespace,
} }
} }
@@ -85,7 +86,7 @@ func (c *packageClient) Update(f *Package) (*Package, error) {
return &result, nil 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(). return c.client.Delete().
Namespace(c.namespace). Namespace(c.namespace).
Resource("packages"). Resource("packages").
@@ -95,12 +96,12 @@ func (c *packageClient) Delete(name string, opts *api.DeleteOptions) error {
Error() Error()
} }
func (c *packageClient) List(opts api.ListOptions) (*PackageList, error) { func (c *packageClient) List(opts metav1.ListOptions) (*PackageList, error) {
var result PackageList var result PackageList
err := c.client.Get(). err := c.client.Get().
Namespace(c.namespace). Namespace(c.namespace).
Resource("packages"). Resource("packages").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Do(). Do().
Into(&result) Into(&result)
if err != nil { if err != nil {
@@ -109,11 +110,11 @@ func (c *packageClient) List(opts api.ListOptions) (*PackageList, error) {
return &result, nil 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(). return c.client.Get().
Prefix("watch"). Prefix("watch").
Namespace(c.namespace). Namespace(c.namespace).
Resource("packages"). Resource("packages").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Watch() Watch()
} }
+28 -27
View File
@@ -14,39 +14,40 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tpr package crd
import ( import (
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/1.5/rest" "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
) )
type ( type (
TimetriggerInterface interface { TimeTriggerInterface interface {
Create(*Timetrigger) (*Timetrigger, error) Create(*TimeTrigger) (*TimeTrigger, error)
Get(name string) (*Timetrigger, error) Get(name string) (*TimeTrigger, error)
Update(*Timetrigger) (*Timetrigger, error) Update(*TimeTrigger) (*TimeTrigger, error)
Delete(name string, options *api.DeleteOptions) error Delete(name string, options *metav1.DeleteOptions) error
List(opts api.ListOptions) (*TimetriggerList, error) List(opts metav1.ListOptions) (*TimeTriggerList, error)
Watch(opts api.ListOptions) (watch.Interface, error) Watch(opts metav1.ListOptions) (watch.Interface, error)
} }
timetriggerClient struct { timeTriggerClient struct {
client *rest.RESTClient client *rest.RESTClient
namespace string namespace string
} }
) )
func MakeTimetriggerInterface(tprClient *rest.RESTClient, namespace string) TimetriggerInterface { func MakeTimeTriggerInterface(crdClient *rest.RESTClient, namespace string) TimeTriggerInterface {
return &timetriggerClient{ return &timeTriggerClient{
client: tprClient, client: crdClient,
namespace: namespace, namespace: namespace,
} }
} }
func (fc *timetriggerClient) Create(f *Timetrigger) (*Timetrigger, error) { func (fc *timeTriggerClient) Create(f *TimeTrigger) (*TimeTrigger, error) {
var result Timetrigger var result TimeTrigger
err := fc.client.Post(). err := fc.client.Post().
Resource("timetriggers"). Resource("timetriggers").
Namespace(fc.namespace). Namespace(fc.namespace).
@@ -58,8 +59,8 @@ func (fc *timetriggerClient) Create(f *Timetrigger) (*Timetrigger, error) {
return &result, nil return &result, nil
} }
func (fc *timetriggerClient) Get(name string) (*Timetrigger, error) { func (fc *timeTriggerClient) Get(name string) (*TimeTrigger, error) {
var result Timetrigger var result TimeTrigger
err := fc.client.Get(). err := fc.client.Get().
Resource("timetriggers"). Resource("timetriggers").
Namespace(fc.namespace). Namespace(fc.namespace).
@@ -71,8 +72,8 @@ func (fc *timetriggerClient) Get(name string) (*Timetrigger, error) {
return &result, nil return &result, nil
} }
func (fc *timetriggerClient) Update(f *Timetrigger) (*Timetrigger, error) { func (fc *timeTriggerClient) Update(f *TimeTrigger) (*TimeTrigger, error) {
var result Timetrigger var result TimeTrigger
err := fc.client.Put(). err := fc.client.Put().
Resource("timetriggers"). Resource("timetriggers").
Namespace(fc.namespace). Namespace(fc.namespace).
@@ -85,7 +86,7 @@ func (fc *timetriggerClient) Update(f *Timetrigger) (*Timetrigger, error) {
return &result, nil 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(). return fc.client.Delete().
Namespace(fc.namespace). Namespace(fc.namespace).
Resource("timetriggers"). Resource("timetriggers").
@@ -95,12 +96,12 @@ func (fc *timetriggerClient) Delete(name string, opts *api.DeleteOptions) error
Error() Error()
} }
func (fc *timetriggerClient) List(opts api.ListOptions) (*TimetriggerList, error) { func (fc *timeTriggerClient) List(opts metav1.ListOptions) (*TimeTriggerList, error) {
var result TimetriggerList var result TimeTriggerList
err := fc.client.Get(). err := fc.client.Get().
Namespace(fc.namespace). Namespace(fc.namespace).
Resource("timetriggers"). Resource("timetriggers").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Do(). Do().
Into(&result) Into(&result)
if err != nil { if err != nil {
@@ -109,11 +110,11 @@ func (fc *timetriggerClient) List(opts api.ListOptions) (*TimetriggerList, error
return &result, nil 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(). return fc.client.Get().
Prefix("watch"). Prefix("watch").
Namespace(fc.namespace). Namespace(fc.namespace).
Resource("timetriggers"). Resource("timetriggers").
VersionedParams(&opts, api.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Watch() Watch()
} }
+228
View File
@@ -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
}
+3 -6
View File
@@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
//"time" //"time"
@@ -68,13 +67,11 @@ func (c *Client) Upload(fr *fetcher.UploadRequest) (*fetcher.UploadResponse, err
return nil, err return nil, err
} }
log.Printf("Received upload response: %v", string(rBody)) uploadResp := fetcher.UploadResponse{}
err = json.Unmarshal([]byte(rBody), &uploadResp)
uploadReq := fetcher.UploadResponse{}
err = json.Unmarshal([]byte(rBody), &uploadReq)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &uploadReq, nil return &uploadResp, nil
} }
+11 -16
View File
@@ -16,23 +16,22 @@ import (
"github.com/mholt/archiver" "github.com/mholt/archiver"
"github.com/satori/go.uuid" "github.com/satori/go.uuid"
"k8s.io/client-go/1.5/kubernetes" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/api"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/crd"
storageSvcClient "github.com/fission/fission/storagesvc/client" storageSvcClient "github.com/fission/fission/storagesvc/client"
"github.com/fission/fission/tpr"
) )
type ( type (
FetchRequestType int FetchRequestType int
FetchRequest struct { FetchRequest struct {
FetchType FetchRequestType `json:"fetchType"` FetchType FetchRequestType `json:"fetchType"`
Package api.ObjectMeta `json:"package"` Package metav1.ObjectMeta `json:"package"`
Url string `json:"url"` Url string `json:"url"`
StorageSvcUrl string `json:"storagesvcurl"` StorageSvcUrl string `json:"storagesvcurl"`
Filename string `json:"filename"` Filename string `json:"filename"`
} }
// UploadRequest send from builder manager describes which // UploadRequest send from builder manager describes which
@@ -51,8 +50,7 @@ type (
Fetcher struct { Fetcher struct {
sharedVolumePath string sharedVolumePath string
fissionClient *tpr.FissionClient fissionClient *crd.FissionClient
kubeClient *kubernetes.Clientset
} }
) )
@@ -63,14 +61,13 @@ const (
) )
func MakeFetcher(sharedVolumePath string) *Fetcher { func MakeFetcher(sharedVolumePath string) *Fetcher {
fissionClient, kubeClient, err := tpr.MakeFissionClient() fissionClient, _, _, err := crd.MakeFissionClient()
if err != nil { if err != nil {
return nil return nil
} }
return &Fetcher{ return &Fetcher{
sharedVolumePath: sharedVolumePath, sharedVolumePath: sharedVolumePath,
fissionClient: fissionClient, fissionClient: fissionClient,
kubeClient: kubeClient,
} }
} }
@@ -155,13 +152,11 @@ func (fetcher *Fetcher) FetchHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), 400) http.Error(w, err.Error(), 400)
return return
} }
log.Printf("fetcher received fetch request: %v", req) log.Printf("fetcher received fetch request and started downloading: %v", req)
tmpFile := req.Filename + ".tmp" tmpFile := req.Filename + ".tmp"
tmpPath := filepath.Join(fetcher.sharedVolumePath, tmpFile) tmpPath := filepath.Join(fetcher.sharedVolumePath, tmpFile)
log.Printf("Start downloading...")
if req.FetchType == FETCH_URL { if req.FetchType == FETCH_URL {
// fetch the file and save it to the tmp path // fetch the file and save it to the tmp path
err := downloadUrl(req.Url, tmpPath) err := downloadUrl(req.Url, tmpPath)
@@ -286,7 +281,7 @@ func (fetcher *Fetcher) UploadHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
log.Println("Start uploading...") log.Println("Starting upload...")
ssClient := storageSvcClient.MakeClient(req.StorageSvcUrl) ssClient := storageSvcClient.MakeClient(req.StorageSvcUrl)
fileID, err := ssClient.Upload(dstFilepath, nil) fileID, err := ssClient.Upload(dstFilepath, nil)
+13 -2
View File
@@ -1,7 +1,18 @@
# A docker image for the func container. # A docker image for the func container.
FROM node:8-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
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 EXPOSE 8888
+18
View File
@@ -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
+14
View File
@@ -0,0 +1,14 @@
FROM alpine:3.5
RUN apk update
RUN apk add --no-cache python python-dev build-base py-pip
RUN pip install --upgrade pip
RUN rm -r /root/.cache
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]
CMD ["server.py"]
@@ -24,12 +24,41 @@ def loadv2():
global userfunc global userfunc
body = request.get_json() body = request.get_json()
filepath = body['filepath'] filepath = body['filepath']
functionName = body['functionName'] handler = body['functionName']
# add filepath into syspath for module import
sys.path.append(filepath) # The value of "functionName" is consist of `<module-name>.<function-name>`.
fn, path, desc = imp.find_module('user', [filepath]) moduleName, funcName = handler.split(".")
mod = imp.load_module('user', fn, path, desc)
userfunc = getattr(mod, functionName) # 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 "" return ""
@app.route('/', methods=['GET', 'POST', 'PUT', 'HEAD', 'OPTIONS', 'DELETE']) @app.route('/', methods=['GET', 'POST', 'PUT', 'HEAD', 'OPTIONS', 'DELETE'])
+27 -1
View File
@@ -2,12 +2,19 @@
This directory contains several examples to get you started using Node.js with Fission. 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: Before running any of these functions, make sure you have created a `nodejs` Fission environment:
``` ```
$ fission env create --name nodejs --image fission/node-env $ 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 ## Function signature
Every Node.js function has the same basic form: Every Node.js function has the same basic form:
@@ -75,7 +82,7 @@ This is a basic example of how you can easily use asynchronous requests in your
$ fission function create --name stock --env nodejs --code stock.js $ fission function create --name stock --env nodejs --code stock.js
# Map GET /stock to your new function # Map GET /stock to your new function
$ fission route create --method GET --url /stock --function stock $ fission route create --method POST --url /stock --function stock
# Run the function. # Run the function.
$ curl -H "Content-Type: application/json" -X POST -d '{"symbol":"AAPL"}' http://$FISSION_ROUTER/stock $ curl -H "Content-Type: application/json" -X POST -d '{"symbol":"AAPL"}' http://$FISSION_ROUTER/stock
@@ -96,3 +103,22 @@ $ fission fn create --name kubeEventsSlack --env nodejs --code kubeEventsSlack.j
# Watch all services in the default namespace: # Watch all services in the default namespace:
$ fission watch create --function kubeEventsSlack --type service --ns default $ fission watch create --function kubeEventsSlack --type service --ns default
``` ```
## weather.js
In this example, the Yahoo Weather API is used to current weather at a given location.
### Usage
```bash
# Upload your function code to fission
$ fission function create --name weather --env nodejs --code weather.js
# Map GET /stock to your new function
$ fission route create --method POST --url /weather --function weather
# Run the function.
$ curl -H "Content-Type: application/json" -X POST -d '{"location":"Sieteiglesias, Spain"}' http://$FISSION_ROUTER/weather
{"text":"It is 2 celsius degrees in Sieteiglesias, Spain and Mostly Clear"}
```
+40
View File
@@ -0,0 +1,40 @@
'use strict';
const rp = require('request-promise-native');
module.exports = async function (context) {
const stringBody = JSON.stringify(context.request.body);
const body = JSON.parse(stringBody);
const location = body.location;
if (!location) {
return {
status: 400,
body: {
text: 'You must provide a location.'
}
};
}
try {
const response = await rp(`https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text="${location}") and u="c"&format=json`);
const condition = JSON.parse(response).query.results.channel.item.condition;
const text = condition.text;
const temperature = condition.temp;
return {
status: 200,
body: {
text: `It is ${temperature} celsius degrees in ${location} and ${text}`
},
headers: {
'Content-Type': 'application/json'
}
};
} catch (e) {
console.error(e);
return {
status: 500,
body: e
};
}
}
+62
View File
@@ -0,0 +1,62 @@
This is an example of creating a deployment package with multiple
files including some static data in text file.
### Create an environment
```
fission env create --name python --image fission/python-env:0.4.0rc --version 2
```
### Create a zip file with all your files
```
zip -jr multifile.zip *.py *.txt
```
### Create a function
Since there are multiple files, you have to specify an _entrypoint_ to
for the function. Its format is `<file name>.<function name>`. In our
example, that's `main.main`, to run function `main` in `main.py`.
```
fission function create --name multifile --env python --code multifile.zip --entrypoint main.main
```
### Test it
```
fission function test --name multifile
```
You should see the "Hello, world" message.
## Updating the function
### Edit a file
```
echo "I said hellooooo!" > message.txt
```
### Update the deployment package
```
zip -jr multifile.zip *.py *.txt
```
### Update the function
```
fission function update --name multifile --code multifile.zip
```
### Test it
```
fission function test --name multifile
```
You should now see your new, edited message.
+11
View File
@@ -0,0 +1,11 @@
from flask import current_app
import sys
import readfile
import os
def main():
current_app.logger.info("Hi")
current_dir = os.path.dirname(__file__)
return readfile.readFile(os.path.join(current_dir, "message.txt"))
+1
View File
@@ -0,0 +1 @@
Hello, world!
+3
View File
@@ -0,0 +1,3 @@
def readFile(name):
with open(name) as f:
return f.read()
+4
View File
@@ -0,0 +1,4 @@
def main():
# You can return any http status code you like, simply place a comma after
# your return statement, and typing in the status code.
return "Not Found\n", 404
-12
View File
@@ -9,7 +9,6 @@ import (
"github.com/fission/fission/buildermgr" "github.com/fission/fission/buildermgr"
"github.com/fission/fission/controller" "github.com/fission/fission/controller"
"github.com/fission/fission/kubewatcher" "github.com/fission/fission/kubewatcher"
"github.com/fission/fission/logger"
"github.com/fission/fission/mqtrigger" "github.com/fission/fission/mqtrigger"
"github.com/fission/fission/poolmgr" "github.com/fission/fission/poolmgr"
"github.com/fission/fission/router" "github.com/fission/fission/router"
@@ -41,11 +40,6 @@ func runKubeWatcher(routerUrl string) {
} }
} }
func runLogger() {
logger.Start()
log.Fatalf("Error: Logger exited.")
}
func runTimer(routerUrl string) { func runTimer(routerUrl string) {
err := timer.Start(routerUrl) err := timer.Start(routerUrl)
if err != nil { if err != nil {
@@ -122,7 +116,6 @@ Usage:
fission-bundle --kubewatcher [--routerUrl=<url>] fission-bundle --kubewatcher [--routerUrl=<url>]
fission-bundle --storageServicePort=<port> --filePath=<filePath> fission-bundle --storageServicePort=<port> --filePath=<filePath>
fission-bundle --builderMgrPort=<port> [--storageSvcUrl=<url>] [--envbuilder-namespace=<namespace>] fission-bundle --builderMgrPort=<port> [--storageSvcUrl=<url>] [--envbuilder-namespace=<namespace>]
fission-bundle --logger
fission-bundle --timer [--routerUrl=<url>] fission-bundle --timer [--routerUrl=<url>]
fission-bundle --mqt [--routerUrl=<url>] fission-bundle --mqt [--routerUrl=<url>]
Options: Options:
@@ -138,7 +131,6 @@ Options:
--filePath=<filePath> Directory to store functions in. --filePath=<filePath> Directory to store functions in.
--namespace=<namespace> Kubernetes namespace in which to run function containers. Defaults to 'fission-function'. --namespace=<namespace> Kubernetes namespace in which to run function containers. Defaults to 'fission-function'.
--kubewatcher Start Kubernetes events watcher. --kubewatcher Start Kubernetes events watcher.
--logger Start logger.
--timer Start Timer. --timer Start Timer.
--mqt Start message queue trigger. --mqt Start message queue trigger.
` `
@@ -174,10 +166,6 @@ Options:
runKubeWatcher(routerUrl) runKubeWatcher(routerUrl)
} }
if arguments["--logger"] == true {
runLogger()
}
if arguments["--timer"] == true { if arguments["--timer"] == true {
runTimer(routerUrl) runTimer(routerUrl)
} }
+36
View File
@@ -17,7 +17,9 @@ limitations under the License.
package main package main
import ( import (
"errors"
"fmt" "fmt"
"net/http"
"os" "os"
"strings" "strings"
@@ -29,6 +31,10 @@ func fatal(msg string) {
os.Exit(1) os.Exit(1)
} }
func warn(msg string) {
os.Stderr.WriteString(msg + "\n")
}
func getClient(serverUrl string) *client.Client { func getClient(serverUrl string) *client.Client {
if len(serverUrl) == 0 { if len(serverUrl) == 0 {
@@ -50,3 +56,33 @@ func checkErr(err error, msg string) {
fatal(fmt.Sprintf("Failed to %v: %v", msg, err)) fatal(fmt.Sprintf("Failed to %v: %v", msg, err))
} }
} }
func httpRequest(method, url, body string, headers []string) *http.Response {
if method == "" {
method = "GET"
}
if method != http.MethodGet &&
method != http.MethodDelete &&
method != http.MethodPost &&
method != http.MethodPut {
fatal(fmt.Sprintf("Invalid HTTP method '%s'.", method))
}
req, err := http.NewRequest(method, url, strings.NewReader(body))
checkErr(err, "create HTTP request")
for _, header := range headers {
headerKeyValue := strings.SplitN(header, ":", 2)
if len(headerKeyValue) != 2 {
checkErr(errors.New(""), "create request without appropriate headers")
}
req.Header.Set(headerKeyValue[0], headerKeyValue[1])
}
client := &http.Client{}
resp, err := client.Do(req)
checkErr(err, "execute HTTP request")
return resp
}
+12 -13
View File
@@ -22,10 +22,10 @@ import (
"text/tabwriter" "text/tabwriter"
"github.com/urfave/cli" "github.com/urfave/cli"
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func envCreate(c *cli.Context) error { func envCreate(c *cli.Context) error {
@@ -55,14 +55,13 @@ func envCreate(c *cli.Context) error {
// Environment API interface version is not specified and // Environment API interface version is not specified and
// builder image is empty, set default interface version // builder image is empty, set default interface version
if envVersion == 0 { if envVersion == 0 {
fmt.Println("Use default environment v1 API interface")
envVersion = 1 envVersion = 1
} }
env := &tpr.Environment{ env := &crd.Environment{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: envName, Name: envName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.EnvironmentSpec{ Spec: fission.EnvironmentSpec{
Version: envVersion, Version: envVersion,
@@ -91,9 +90,9 @@ func envGet(c *cli.Context) error {
fatal("Need a name, use --name.") fatal("Need a name, use --name.")
} }
m := &api.ObjectMeta{ m := &metav1.ObjectMeta{
Name: envName, Name: envName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
} }
env, err := client.EnvironmentGet(m) env, err := client.EnvironmentGet(m)
checkErr(err, "get environment") checkErr(err, "get environment")
@@ -121,9 +120,9 @@ func envUpdate(c *cli.Context) error {
fatal("Need --image to specify env image, or use --builder to specify env builder, or use --buildcmd to specify new build command.") fatal("Need --image to specify env image, or use --builder to specify env builder, or use --buildcmd to specify new build command.")
} }
env, err := client.EnvironmentGet(&api.ObjectMeta{ env, err := client.EnvironmentGet(&metav1.ObjectMeta{
Name: envName, Name: envName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
checkErr(err, "find environment") checkErr(err, "find environment")
@@ -132,7 +131,7 @@ func envUpdate(c *cli.Context) error {
} }
if env.Spec.Version == 1 && (len(envBuilderImg) > 0 || len(envBuildCmd) > 0) { if env.Spec.Version == 1 && (len(envBuilderImg) > 0 || len(envBuildCmd) > 0) {
fatal("Environment v1 API interface doesn't supported environment builder.") fatal("Version 1 Environments do not support builders. Must specify --version=2.")
} }
if len(envBuilderImg) > 0 { if len(envBuilderImg) > 0 {
@@ -157,9 +156,9 @@ func envDelete(c *cli.Context) error {
fatal("Need a name , use --name.") fatal("Need a name , use --name.")
} }
m := &api.ObjectMeta{ m := &metav1.ObjectMeta{
Name: envName, Name: envName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
} }
err := client.EnvironmentDelete(m) err := client.EnvironmentDelete(m)
checkErr(err, "delete environment") checkErr(err, "delete environment")
+112 -39
View File
@@ -20,23 +20,28 @@ import (
"context" "context"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http"
"net/url"
"os" "os"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"time" "time"
"github.com/dchest/uniuri"
"github.com/satori/go.uuid" "github.com/satori/go.uuid"
"github.com/urfave/cli" "github.com/urfave/cli"
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/controller/client" "github.com/fission/fission/controller/client"
"github.com/fission/fission/crd"
"github.com/fission/fission/fission/logdb" "github.com/fission/fission/fission/logdb"
storageSvcClient "github.com/fission/fission/storagesvc/client" storageSvcClient "github.com/fission/fission/storagesvc/client"
"github.com/fission/fission/tpr"
) )
func fileSize(filePath string) int64 { func fileSize(filePath string) int64 {
@@ -84,36 +89,48 @@ func createArchive(client *client.Client, fileName string) *fission.Archive {
return &archive return &archive
} }
func createPackage(client *client.Client, envName, srcArchiveName, deployArchiveName, buildcmd string) *api.ObjectMeta { func createPackage(client *client.Client, fnName, envName, srcArchiveName, deployArchiveName, buildcmd string) *metav1.ObjectMeta {
pkgSpec := fission.PackageSpec{ pkgSpec := fission.PackageSpec{
Environment: fission.EnvironmentReference{ Environment: fission.EnvironmentReference{
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
Name: envName, Name: envName,
}, },
} }
var pkgStatus fission.BuildStatus = fission.BuildStatusSucceeded
var pkgStatus fission.BuildStatus
if len(deployArchiveName) > 0 { if len(deployArchiveName) > 0 {
pkgSpec.Deployment = *createArchive(client, deployArchiveName) pkgSpec.Deployment = *createArchive(client, deployArchiveName)
if len(srcArchiveName) > 0 {
fmt.Println("Deployment may be overwritten by builder manager after source package compilation")
}
} }
if len(srcArchiveName) > 0 { if len(srcArchiveName) > 0 {
pkgSpec.Source = *createArchive(client, srcArchiveName) pkgSpec.Source = *createArchive(client, srcArchiveName)
// set pending status to package }
// start a build only when a package has no deploy archive
if len(srcArchiveName) > 0 && len(deployArchiveName) == 0 {
pkgStatus = fission.BuildStatusPending pkgStatus = fission.BuildStatusPending
} else {
pkgStatus = fission.BuildStatusNone
} }
if len(buildcmd) > 0 { if len(buildcmd) > 0 {
pkgSpec.BuildCommand = buildcmd pkgSpec.BuildCommand = buildcmd
} }
pkgName := strings.ToLower(uuid.NewV4().String()) fnList, err := json.Marshal([]string{fnName})
pkg := &tpr.Package{ checkErr(err, "encode json")
Metadata: api.ObjectMeta{
Name: pkgName, annotation := map[string]string{
Namespace: api.NamespaceDefault, "createdForFunction": fnName,
"usedByFunctions": string(fnList),
}
pkgName := strings.ToLower(fmt.Sprintf("%v-%v", fnName, uniuri.NewLen(6)))
pkg := &crd.Package{
Metadata: metav1.ObjectMeta{
Name: pkgName,
Namespace: metav1.NamespaceDefault,
Annotations: annotation,
}, },
Spec: pkgSpec, Spec: pkgSpec,
Status: fission.PackageStatus{ Status: fission.PackageStatus{
@@ -134,6 +151,34 @@ func getContents(filePath string) []byte {
return code return code
} }
func printPodLogs(c *cli.Context) error {
fnName := c.String("name")
if len(fnName) == 0 {
fatal("Need --name argument.")
}
queryURL, err := url.Parse(c.GlobalString("server"))
checkErr(err, "parse the base URL")
queryURL.Path = fmt.Sprintf("/proxy/logs/%s", fnName)
req, err := http.NewRequest("POST", queryURL.String(), nil)
checkErr(err, "create logs request")
httpClient := http.Client{}
resp, err := httpClient.Do(req)
checkErr(err, "execute get logs request")
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return errors.New("get logs from pod directly")
}
body, err := ioutil.ReadAll(resp.Body)
checkErr(err, "read the response body")
fmt.Println(string(body))
return nil
}
func fnCreate(c *cli.Context) error { func fnCreate(c *cli.Context) error {
client := getClient(c.GlobalString("server")) client := getClient(c.GlobalString("server"))
@@ -163,21 +208,18 @@ func fnCreate(c *cli.Context) error {
entrypoint := c.String("entrypoint") entrypoint := c.String("entrypoint")
buildcmd := c.String("buildcmd") buildcmd := c.String("buildcmd")
if len(buildcmd) == 0 {
buildcmd = "/builder"
}
pkgMetadata := createPackage(client, envName, srcArchiveName, deployArchiveName, buildcmd) pkgMetadata := createPackage(client, fnName, envName, srcArchiveName, deployArchiveName, buildcmd)
function := &tpr.Function{ function := &crd.Function{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: fnName, Name: fnName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.FunctionSpec{ Spec: fission.FunctionSpec{
Environment: fission.EnvironmentReference{ Environment: fission.EnvironmentReference{
Name: envName, Name: envName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Package: fission.FunctionPackageRef{ Package: fission.FunctionPackageRef{
FunctionName: entrypoint, FunctionName: entrypoint,
@@ -205,10 +247,10 @@ func fnCreate(c *cli.Context) error {
method = "GET" method = "GET"
} }
triggerName := uuid.NewV4().String() triggerName := uuid.NewV4().String()
ht := &tpr.Httptrigger{ ht := &crd.HTTPTrigger{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: triggerName, Name: triggerName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.HTTPTriggerSpec{ Spec: fission.HTTPTriggerSpec{
RelativeURL: triggerUrl, RelativeURL: triggerUrl,
@@ -233,14 +275,14 @@ func fnGet(c *cli.Context) error {
if len(fnName) == 0 { if len(fnName) == 0 {
fatal("Need name of function, use --name") fatal("Need name of function, use --name")
} }
m := &api.ObjectMeta{ m := &metav1.ObjectMeta{
Name: fnName, Name: fnName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
} }
fn, err := client.FunctionGet(m) fn, err := client.FunctionGet(m)
checkErr(err, "get function") checkErr(err, "get function")
pkg, err := client.PackageGet(&api.ObjectMeta{ pkg, err := client.PackageGet(&metav1.ObjectMeta{
Name: fn.Spec.Package.PackageRef.Name, Name: fn.Spec.Package.PackageRef.Name,
Namespace: fn.Spec.Package.PackageRef.Namespace, Namespace: fn.Spec.Package.PackageRef.Namespace,
}) })
@@ -258,9 +300,9 @@ func fnGetMeta(c *cli.Context) error {
fatal("Need name of function, use --name") fatal("Need name of function, use --name")
} }
m := &api.ObjectMeta{ m := &metav1.ObjectMeta{
Name: fnName, Name: fnName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
} }
f, err := client.FunctionGet(m) f, err := client.FunctionGet(m)
@@ -286,9 +328,9 @@ func fnUpdate(c *cli.Context) error {
fatal("--package is deprecated, please use --deploy instead.") fatal("--package is deprecated, please use --deploy instead.")
} }
function, err := client.FunctionGet(&api.ObjectMeta{ function, err := client.FunctionGet(&metav1.ObjectMeta{
Name: fnName, Name: fnName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
checkErr(err, fmt.Sprintf("read function '%v'", fnName)) checkErr(err, fmt.Sprintf("read function '%v'", fnName))
@@ -312,7 +354,7 @@ func fnUpdate(c *cli.Context) error {
function.Spec.Package.FunctionName = entrypoint function.Spec.Package.FunctionName = entrypoint
} }
pkg, err := client.PackageGet(&api.ObjectMeta{ pkg, err := client.PackageGet(&metav1.ObjectMeta{
Name: function.Spec.Package.PackageRef.Name, Name: function.Spec.Package.PackageRef.Name,
Namespace: function.Spec.Package.PackageRef.Namespace, Namespace: function.Spec.Package.PackageRef.Namespace,
}) })
@@ -326,7 +368,7 @@ func fnUpdate(c *cli.Context) error {
if len(deployArchiveName) > 0 || len(srcArchiveName) > 0 { if len(deployArchiveName) > 0 || len(srcArchiveName) > 0 {
// create a new package for function // create a new package for function
pkgMetadata := createPackage(client, pkgMetadata := createPackage(client, function.Metadata.Name,
function.Spec.Environment.Name, srcArchiveName, deployArchiveName, buildcmd) function.Spec.Environment.Name, srcArchiveName, deployArchiveName, buildcmd)
// update function spec with resource version // update function spec with resource version
@@ -352,9 +394,9 @@ func fnDelete(c *cli.Context) error {
fatal("Need name of function, use --name") fatal("Need name of function, use --name")
} }
m := &api.ObjectMeta{ m := &metav1.ObjectMeta{
Name: fnName, Name: fnName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
} }
err := client.FunctionDelete(m) err := client.FunctionDelete(m)
@@ -383,6 +425,7 @@ func fnList(c *cli.Context) error {
} }
func fnLogs(c *cli.Context) error { func fnLogs(c *cli.Context) error {
client := getClient(c.GlobalString("server")) client := getClient(c.GlobalString("server"))
fnName := c.String("name") fnName := c.String("name")
@@ -396,9 +439,9 @@ func fnLogs(c *cli.Context) error {
} }
fnPod := c.String("pod") fnPod := c.String("pod")
m := &api.ObjectMeta{ m := &metav1.ObjectMeta{
Name: fnName, Name: fnName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
} }
f, err := client.FunctionGet(m) f, err := client.FunctionGet(m)
@@ -469,7 +512,7 @@ func fnPods(c *cli.Context) error {
dbType = logdb.INFLUXDB dbType = logdb.INFLUXDB
} }
m := &api.ObjectMeta{Name: fnName} m := &metav1.ObjectMeta{Name: fnName}
f, err := client.FunctionGet(m) f, err := client.FunctionGet(m)
checkErr(err, "get function") checkErr(err, "get function")
@@ -497,3 +540,33 @@ func fnPods(c *cli.Context) error {
return err return err
} }
func fnTest(c *cli.Context) error {
fnName := c.String("name")
routerURL := os.Getenv("FISSION_ROUTER")
if len(routerURL) == 0 {
fatal("Need FISSION_ROUTER set to your fission router.")
}
url := fmt.Sprintf("http://%s/fission-function/%s", routerURL, fnName)
resp := httpRequest(c.String("method"), url, c.String("body"), c.StringSlice("header"))
if resp.StatusCode < 400 {
body, err := ioutil.ReadAll(resp.Body)
checkErr(err, "Function test")
fmt.Print(string(body))
defer resp.Body.Close()
return nil
}
body, err := ioutil.ReadAll(resp.Body)
checkErr(err, "read log response from pod")
fmt.Printf("Error calling function %v: %v %v", fnName, resp.StatusCode, string(body))
defer resp.Body.Close()
err = printPodLogs(c)
if err != nil {
fnLogs(c)
}
return nil
}
+9 -9
View File
@@ -25,10 +25,10 @@ import (
"github.com/satori/go.uuid" "github.com/satori/go.uuid"
"github.com/urfave/cli" "github.com/urfave/cli"
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
// returns one of http.Method* // returns one of http.Method*
@@ -76,10 +76,10 @@ func htCreate(c *cli.Context) error {
// just name triggers by uuid. // just name triggers by uuid.
triggerName := uuid.NewV4().String() triggerName := uuid.NewV4().String()
ht := &tpr.Httptrigger{ ht := &crd.HTTPTrigger{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: triggerName, Name: triggerName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.HTTPTriggerSpec{ Spec: fission.HTTPTriggerSpec{
RelativeURL: triggerUrl, RelativeURL: triggerUrl,
@@ -115,9 +115,9 @@ func htUpdate(c *cli.Context) error {
fatal("Nothing to update. Use --function to specify a new function.") fatal("Nothing to update. Use --function to specify a new function.")
} }
ht, err := client.HTTPTriggerGet(&api.ObjectMeta{ ht, err := client.HTTPTriggerGet(&metav1.ObjectMeta{
Name: htName, Name: htName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
checkErr(err, "get HTTP trigger") checkErr(err, "get HTTP trigger")
@@ -139,9 +139,9 @@ func htDelete(c *cli.Context) error {
fatal("Need name of trigger to delete, use --name") fatal("Need name of trigger to delete, use --name")
} }
err := client.HTTPTriggerDelete(&api.ObjectMeta{ err := client.HTTPTriggerDelete(&metav1.ObjectMeta{
Name: htName, Name: htName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
checkErr(err, "delete trigger") checkErr(err, "delete trigger")
+8 -7
View File
@@ -96,14 +96,15 @@ func (influx InfluxDB) GetLogs(filter LogFilter) ([]LogEntry, error) {
log.Fatal(err) log.Fatal(err)
} }
logEntries = append(logEntries, LogEntry{ logEntries = append(logEntries, LogEntry{
//The attributes of the LogEntry are selected as relative to their position in InfluxDB's line protocol response
Timestamp: t, Timestamp: t,
Container: row[2].(string), Container: row[2].(string), //docker_container_id
FuncName: row[3].(string), FuncName: row[8].(string), //kubernetes_labels_functionName
FuncUid: row[4].(string), FuncUid: row[3].(string), //funcuid
Message: strings.TrimSuffix(row[5].(string), "\n"), Message: strings.TrimSuffix(row[17].(string), "\n"), //log field
Namespace: row[6].(string), Namespace: row[14].(string), //kubernetes_namespace_name
Pod: row[7].(string), Pod: row[15].(string), //kubernetes_pod_name
Stream: row[8].(string), Stream: row[18].(string), //stream
}) })
} }
} }
+14 -1
View File
@@ -26,7 +26,7 @@ func main() {
app := cli.NewApp() app := cli.NewApp()
app.Name = "fission" app.Name = "fission"
app.Usage = "Serverless functions for Kubernetes" app.Usage = "Serverless functions for Kubernetes"
app.Version = "0.3.0" app.Version = "0.4.0"
app.Flags = []cli.Flag{ app.Flags = []cli.Flag{
cli.StringFlag{Name: "server", Usage: "Fission server URL", EnvVar: "FISSION_URL"}, cli.StringFlag{Name: "server", Usage: "Fission server URL", EnvVar: "FISSION_URL"},
@@ -47,8 +47,11 @@ func main() {
fnFollowFlag := cli.BoolFlag{Name: "follow, f", Usage: "specify if the logs should be streamed"} fnFollowFlag := cli.BoolFlag{Name: "follow, f", Usage: "specify if the logs should be streamed"}
fnDetailFlag := cli.BoolFlag{Name: "detail, d", Usage: "display detailed information"} fnDetailFlag := cli.BoolFlag{Name: "detail, d", Usage: "display detailed information"}
fnLogDBTypeFlag := cli.StringFlag{Name: "dbtype", Usage: "log database type, e.g. influxdb (currently only influxdb is supported)"} fnLogDBTypeFlag := cli.StringFlag{Name: "dbtype", Usage: "log database type, e.g. influxdb (currently only influxdb is supported)"}
fnBodyFlag := cli.StringFlag{Name: "body, b", Usage: "request body"}
fnHeaderFlag := cli.StringSliceFlag{Name: "header, H", Usage: "request headers"}
fnEntryPointFlag := cli.StringFlag{Name: "entrypoint", Usage: "entry point for environment v2 to load with"} fnEntryPointFlag := cli.StringFlag{Name: "entrypoint", Usage: "entry point for environment v2 to load with"}
fnBuildCmdFlag := cli.StringFlag{Name: "buildcmd", Usage: "build command for builder to run with"} fnBuildCmdFlag := cli.StringFlag{Name: "buildcmd", Usage: "build command for builder to run with"}
fnSubcommands := []cli.Command{ fnSubcommands := []cli.Command{
{Name: "create", Usage: "Create new function (and optionally, an HTTP route to it)", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnPackageFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag, htUrlFlag, htMethodFlag}, Action: fnCreate}, {Name: "create", Usage: "Create new function (and optionally, an HTTP route to it)", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnPackageFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag, htUrlFlag, htMethodFlag}, Action: fnCreate},
{Name: "get", Usage: "Get function source code", Flags: []cli.Flag{fnNameFlag}, Action: fnGet}, {Name: "get", Usage: "Get function source code", Flags: []cli.Flag{fnNameFlag}, Action: fnGet},
@@ -58,6 +61,7 @@ func main() {
{Name: "list", Usage: "List all functions", Flags: []cli.Flag{}, Action: fnList}, {Name: "list", Usage: "List all functions", Flags: []cli.Flag{}, Action: fnList},
{Name: "logs", Usage: "Display function logs", Flags: []cli.Flag{fnNameFlag, fnPodFlag, fnFollowFlag, fnDetailFlag, fnLogDBTypeFlag}, Action: fnLogs}, {Name: "logs", Usage: "Display function logs", Flags: []cli.Flag{fnNameFlag, fnPodFlag, fnFollowFlag, fnDetailFlag, fnLogDBTypeFlag}, Action: fnLogs},
{Name: "pods", Usage: "Display function pods", Flags: []cli.Flag{fnNameFlag, fnLogDBTypeFlag}, Action: fnPods}, {Name: "pods", Usage: "Display function pods", Flags: []cli.Flag{fnNameFlag, fnLogDBTypeFlag}, Action: fnPods},
{Name: "test", Usage: "Test a function", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag, fnPackageFlag, fnSrcArchiveFlag, htMethodFlag, fnBodyFlag, fnHeaderFlag}, Action: fnTest},
} }
// httptriggers // httptriggers
@@ -131,6 +135,14 @@ func main() {
{Name: "dump", Usage: "Dump all state from a v0.1 fission installation", Flags: []cli.Flag{upgradeFileFlag}, Action: upgradeDumpState}, {Name: "dump", Usage: "Dump all state from a v0.1 fission installation", Flags: []cli.Flag{upgradeFileFlag}, Action: upgradeDumpState},
{Name: "restore", Usage: "Restore state dumped from a v0.1 install into a v0.2+ install", Flags: []cli.Flag{upgradeFileFlag}, Action: upgradeRestoreState}, {Name: "restore", Usage: "Restore state dumped from a v0.1 install into a v0.2+ install", Flags: []cli.Flag{upgradeFileFlag}, Action: upgradeRestoreState},
} }
migrateFileFlag := cli.StringFlag{Name: "file", Usage: "JSON file containing all CRDs"}
migrateSubCommands := []cli.Command{
{Name: "dump", Usage: "Dump all state from a pre-0.4 Fission installation (which used ThirdPartyResources) into a JSON file", Flags: []cli.Flag{migrateFileFlag}, Action: migrateDumpTPR},
{Name: "delete", Usage: "Delete all TPRs", Flags: []cli.Flag{}, Action: migrateDeleteTPR},
{Name: "restore", Usage: "Restore state dumped from a pre-0.4 Fission cluster. Requires Fission 0.4, which uses Kubernetes CustomResources.", Flags: []cli.Flag{migrateFileFlag}, Action: migrateRestoreCRD},
}
app.Commands = []cli.Command{ app.Commands = []cli.Command{
{Name: "function", Aliases: []string{"fn"}, Usage: "Create, update and manage functions", Subcommands: fnSubcommands}, {Name: "function", Aliases: []string{"fn"}, Usage: "Create, update and manage functions", Subcommands: fnSubcommands},
{Name: "httptrigger", Aliases: []string{"ht", "route"}, Usage: "Manage HTTP triggers (routes) for functions", Subcommands: htSubcommands}, {Name: "httptrigger", Aliases: []string{"ht", "route"}, Usage: "Manage HTTP triggers (routes) for functions", Subcommands: htSubcommands},
@@ -139,6 +151,7 @@ func main() {
{Name: "environment", Aliases: []string{"env"}, Usage: "Manage environments", Subcommands: envSubcommands}, {Name: "environment", Aliases: []string{"env"}, Usage: "Manage environments", Subcommands: envSubcommands},
{Name: "watch", Aliases: []string{"w"}, Usage: "Manage watches", Subcommands: wSubCommands}, {Name: "watch", Aliases: []string{"w"}, Usage: "Manage watches", Subcommands: wSubCommands},
{Name: "upgrade", Aliases: []string{}, Usage: "Upgrade tool from fission v0.1", Subcommands: upgradeSubCommands}, {Name: "upgrade", Aliases: []string{}, Usage: "Upgrade tool from fission v0.1", Subcommands: upgradeSubCommands},
{Name: "tpr2crd", Aliases: []string{}, Usage: "Migrate tool for TPR to CRD", Subcommands: migrateSubCommands},
} }
app.Run(os.Args) app.Run(os.Args)
+213
View File
@@ -0,0 +1,213 @@
/*
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 main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"github.com/urfave/cli"
"github.com/fission/fission"
"github.com/fission/fission/controller/client"
"github.com/fission/fission/crd"
"github.com/fission/fission/mqtrigger/messageQueue"
)
type (
TPRResource struct {
Packages []crd.Package `json:"packages"`
Functions []crd.Function `json:"functions"`
Environments []crd.Environment `json:"environments"`
HTTPTriggers []crd.HTTPTrigger `json:"httptriggers"`
Mqtriggers []crd.MessageQueueTrigger `json:"mqtriggers"`
TimeTriggers []crd.TimeTrigger `json:"timetriggers"`
Watches []crd.KubernetesWatchTrigger `json:"watches"`
}
)
func migrateDumpTPRResource(client *client.Client, filename string) {
pkgs, err := client.PackageList()
checkErr(err, "dump packages")
fns, err := client.FunctionList()
checkErr(err, "dump functions")
httpTriggers, err := client.HTTPTriggerList()
checkErr(err, "dump http triggers")
envs, err := client.EnvironmentList()
checkErr(err, "dump environments")
watches, err := client.WatchList()
checkErr(err, "dump watches")
timeTriggers, err := client.TimeTriggerList()
checkErr(err, "dump time triggers")
mqTriggers, err := client.MessageQueueTriggerList(messageQueue.NATS)
checkErr(err, "dump message queue triggers")
tprResource := TPRResource{
Packages: pkgs,
Functions: fns,
HTTPTriggers: httpTriggers,
Environments: envs,
Watches: watches,
TimeTriggers: timeTriggers,
Mqtriggers: mqTriggers,
}
// serialize tprResource
out, err := json.MarshalIndent(tprResource, "", " ")
checkErr(err, "serialize tpr state")
// dump to file fission-tpr.json
if len(filename) == 0 {
filename = "fission-tpr.json"
}
err = ioutil.WriteFile(filename, out, 0644)
checkErr(err, "write file")
fmt.Printf("Done: Saved %v packages, %v functions, %v HTTP triggers, %v watches, %v message queue triggers, %v time triggers.\n",
len(tprResource.Packages), len(tprResource.Functions), len(tprResource.HTTPTriggers), len(tprResource.Watches), len(tprResource.Mqtriggers),
len(tprResource.TimeTriggers))
}
func migrateDumpTPR(c *cli.Context) error {
filename := c.String("file")
client := getClient(c.GlobalString("server"))
migrateDumpTPRResource(client, filename)
return nil
}
func migrateDeleteTPR(c *cli.Context) error {
server := c.GlobalString("server")
relativeUrl := fmt.Sprintf("%v/%v", server, "v2/deleteTpr")
req, err := http.NewRequest("DELETE", relativeUrl, nil)
checkErr(err, "connect to fission server")
resp, err := http.DefaultClient.Do(req)
checkErr(err, "delete tpr resources")
defer resp.Body.Close()
if resp.StatusCode == 404 {
msg := fmt.Sprintf("Server %v isn't support deleteTpr method. Use --server to point at a 0.4.0+ Fission server.", server)
fatal(msg)
}
return nil
}
// checkAlreadyExistsError helps to check whether the error is AlreadyExists error or not.
func checkAlreadyExistsError(err error, msg string) {
fe, ok := err.(fission.Error)
// ignore AlreadyExists error, since a resource may exist.
if !ok || fe.Code != fission.ErrorNameExists {
checkErr(err, msg)
}
}
func migrateRestoreCRD(c *cli.Context) error {
filename := c.String("file")
if len(filename) == 0 {
filename = "fission-tpr.json"
}
contents, err := ioutil.ReadFile(filename)
checkErr(err, fmt.Sprintf("open file %v", filename))
var tprResource TPRResource
err = json.Unmarshal(contents, &tprResource)
checkErr(err, "parse dumped tpr")
client := getClient(c.GlobalString("server"))
// 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.
// create envs
for _, e := range tprResource.Environments {
e.Metadata.ResourceVersion = ""
_, err = client.EnvironmentCreate(&crd.Environment{
Metadata: e.Metadata,
Spec: e.Spec,
})
checkAlreadyExistsError(err, fmt.Sprintf("create environment %v", e.Metadata.Name))
}
// create httptriggers
for _, t := range tprResource.HTTPTriggers {
t.Metadata.ResourceVersion = ""
_, err = client.HTTPTriggerCreate(&crd.HTTPTrigger{
Metadata: t.Metadata,
Spec: t.Spec,
})
checkAlreadyExistsError(err, fmt.Sprintf("create http trigger %v", t.Metadata.Name))
}
// create mqtriggers
for _, t := range tprResource.Mqtriggers {
t.Metadata.ResourceVersion = ""
_, err = client.MessageQueueTriggerCreate(&crd.MessageQueueTrigger{
Metadata: t.Metadata,
Spec: t.Spec,
})
checkAlreadyExistsError(err, fmt.Sprintf("create http trigger %v", t.Metadata.Name))
}
// create time triggers
for _, t := range tprResource.TimeTriggers {
t.Metadata.ResourceVersion = ""
_, err = client.TimeTriggerCreate(&crd.TimeTrigger{
Metadata: t.Metadata,
Spec: t.Spec,
})
checkAlreadyExistsError(err, fmt.Sprintf("create time trigger %v", t.Metadata.Name))
}
// create watches
for _, t := range tprResource.Watches {
t.Metadata.ResourceVersion = ""
_, err = client.WatchCreate(&crd.KubernetesWatchTrigger{
Metadata: t.Metadata,
Spec: t.Spec,
})
checkAlreadyExistsError(err, fmt.Sprintf("create kubernetes watch trigger %v", t.Metadata.Name))
}
// create packages
for _, p := range tprResource.Packages {
p.Metadata.ResourceVersion = ""
_, err = client.PackageCreate(&crd.Package{
Metadata: p.Metadata,
Spec: p.Spec,
})
checkAlreadyExistsError(err, fmt.Sprintf("create function %v", p.Metadata.Name))
}
// create functions
for _, f := range tprResource.Functions {
f.Metadata.ResourceVersion = ""
_, err = client.FunctionCreate(&crd.Function{
Metadata: f.Metadata,
Spec: f.Spec,
})
checkAlreadyExistsError(err, fmt.Sprintf("create function %v", f.Metadata.Name))
}
return nil
}
+9 -9
View File
@@ -23,11 +23,11 @@ import (
"github.com/satori/go.uuid" "github.com/satori/go.uuid"
"github.com/urfave/cli" "github.com/urfave/cli"
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/crd"
"github.com/fission/fission/mqtrigger/messageQueue" "github.com/fission/fission/mqtrigger/messageQueue"
"github.com/fission/fission/tpr"
) )
func mqtCreate(c *cli.Context) error { func mqtCreate(c *cli.Context) error {
@@ -72,10 +72,10 @@ func mqtCreate(c *cli.Context) error {
checkMQTopicAvailability(mqType, topic, respTopic) checkMQTopicAvailability(mqType, topic, respTopic)
mqt := tpr.Messagequeuetrigger{ mqt := crd.MessageQueueTrigger{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: mqtName, Name: mqtName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.MessageQueueTriggerSpec{ Spec: fission.MessageQueueTriggerSpec{
FunctionReference: fission.FunctionReference{ FunctionReference: fission.FunctionReference{
@@ -111,9 +111,9 @@ func mqtUpdate(c *cli.Context) error {
fnName := c.String("function") fnName := c.String("function")
contentType := c.String("contenttype") contentType := c.String("contenttype")
mqt, err := client.MessageQueueTriggerGet(&api.ObjectMeta{ mqt, err := client.MessageQueueTriggerGet(&metav1.ObjectMeta{
Name: mqtName, Name: mqtName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
checkErr(err, "get Time trigger") checkErr(err, "get Time trigger")
@@ -155,9 +155,9 @@ func mqtDelete(c *cli.Context) error {
fatal("Need name of trigger to delete, use --name") fatal("Need name of trigger to delete, use --name")
} }
err := client.MessageQueueTriggerDelete(&api.ObjectMeta{ err := client.MessageQueueTriggerDelete(&metav1.ObjectMeta{
Name: mqtName, Name: mqtName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
checkErr(err, "delete trigger") checkErr(err, "delete trigger")
+9 -9
View File
@@ -23,10 +23,10 @@ import (
"github.com/satori/go.uuid" "github.com/satori/go.uuid"
"github.com/urfave/cli" "github.com/urfave/cli"
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func ttCreate(c *cli.Context) error { func ttCreate(c *cli.Context) error {
@@ -45,10 +45,10 @@ func ttCreate(c *cli.Context) error {
fatal("Need a cron spec like '0 30 * * *', '@every 1h30m', or '@hourly'; use --cron") fatal("Need a cron spec like '0 30 * * *', '@every 1h30m', or '@hourly'; use --cron")
} }
tt := &tpr.Timetrigger{ tt := &crd.TimeTrigger{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: name, Name: name,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.TimeTriggerSpec{ Spec: fission.TimeTriggerSpec{
Cron: cron, Cron: cron,
@@ -77,9 +77,9 @@ func ttUpdate(c *cli.Context) error {
fatal("Need name of trigger, use --name") fatal("Need name of trigger, use --name")
} }
tt, err := client.TimeTriggerGet(&api.ObjectMeta{ tt, err := client.TimeTriggerGet(&metav1.ObjectMeta{
Name: ttName, Name: ttName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
checkErr(err, "get time trigger") checkErr(err, "get time trigger")
@@ -113,9 +113,9 @@ func ttDelete(c *cli.Context) error {
fatal("Need name of trigger to delete, use --name") fatal("Need name of trigger to delete, use --name")
} }
err := client.TimeTriggerDelete(&api.ObjectMeta{ err := client.TimeTriggerDelete(&metav1.ObjectMeta{
Name: ttName, Name: ttName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
checkErr(err, "delete trigger") checkErr(err, "delete trigger")
+30 -30
View File
@@ -12,10 +12,10 @@ import (
"github.com/dchest/uniuri" "github.com/dchest/uniuri"
"github.com/urfave/cli" "github.com/urfave/cli"
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
"github.com/fission/fission/v1" "github.com/fission/fission/v1"
) )
@@ -23,9 +23,9 @@ type (
V1FissionState struct { V1FissionState struct {
Functions []v1.Function `json:"functions"` Functions []v1.Function `json:"functions"`
Environments []v1.Environment `json:"environments"` Environments []v1.Environment `json:"environments"`
Httptriggers []v1.HTTPTrigger `json:"httptriggers"` HTTPTriggers []v1.HTTPTrigger `json:"httptriggers"`
Mqtriggers []v1.MessageQueueTrigger `json:"mqtriggers"` Mqtriggers []v1.MessageQueueTrigger `json:"mqtriggers"`
Timetriggers []v1.TimeTrigger `json:"timetriggers"` TimeTriggers []v1.TimeTrigger `json:"timetriggers"`
Watches []v1.Watch `json:"watches"` Watches []v1.Watch `json:"watches"`
NameChanges map[string]string `json:"namechanges"` NameChanges map[string]string `json:"namechanges"`
} }
@@ -133,7 +133,7 @@ func upgradeDumpV1State(v1url string, filename string) {
fmt.Println("Getting routes") fmt.Println("Getting routes")
resp = get(v1url + "/triggers/http") resp = get(v1url + "/triggers/http")
err = json.Unmarshal(resp, &v1state.Httptriggers) err = json.Unmarshal(resp, &v1state.HTTPTriggers)
checkErr(err, "parse server response") checkErr(err, "parse server response")
fmt.Println("Getting message queue triggers") fmt.Println("Getting message queue triggers")
@@ -143,7 +143,7 @@ func upgradeDumpV1State(v1url string, filename string) {
fmt.Println("Getting time triggers") fmt.Println("Getting time triggers")
resp = get(v1url + "/triggers/time") resp = get(v1url + "/triggers/time")
err = json.Unmarshal(resp, &v1state.Timetriggers) err = json.Unmarshal(resp, &v1state.TimeTriggers)
checkErr(err, "parse server response") checkErr(err, "parse server response")
fmt.Println("Getting function list") fmt.Println("Getting function list")
@@ -163,7 +163,7 @@ func upgradeDumpV1State(v1url string, filename string) {
funcMetaSet[f.Metadata] = true funcMetaSet[f.Metadata] = true
nr.trackName(f.Metadata.Name) nr.trackName(f.Metadata.Name)
} }
for _, t := range v1state.Httptriggers { for _, t := range v1state.HTTPTriggers {
funcMetaSet[t.Function] = true funcMetaSet[t.Function] = true
nr.trackName(t.Metadata.Name) nr.trackName(t.Metadata.Name)
} }
@@ -175,7 +175,7 @@ func upgradeDumpV1State(v1url string, filename string) {
funcMetaSet[t.Function] = true funcMetaSet[t.Function] = true
nr.trackName(t.Metadata.Name) nr.trackName(t.Metadata.Name)
} }
for _, t := range v1state.Timetriggers { for _, t := range v1state.TimeTriggers {
funcMetaSet[t.Function] = true funcMetaSet[t.Function] = true
nr.trackName(t.Metadata.Name) nr.trackName(t.Metadata.Name)
} }
@@ -225,7 +225,7 @@ func upgradeDumpV1State(v1url string, filename string) {
checkErr(err, "write file") checkErr(err, "write file")
fmt.Printf("Done: Saved %v functions, %v HTTP triggers, %v watches, %v message queue triggers, %v time triggers.\n", fmt.Printf("Done: Saved %v functions, %v HTTP triggers, %v watches, %v message queue triggers, %v time triggers.\n",
len(v1state.Functions), len(v1state.Httptriggers), len(v1state.Watches), len(v1state.Mqtriggers), len(v1state.Timetriggers)) len(v1state.Functions), len(v1state.HTTPTriggers), len(v1state.Watches), len(v1state.Mqtriggers), len(v1state.TimeTriggers))
} }
func functionRefFromV1Metadata(m *v1.Metadata, nameRemap map[string]string) *fission.FunctionReference { func functionRefFromV1Metadata(m *v1.Metadata, nameRemap map[string]string) *fission.FunctionReference {
@@ -235,10 +235,10 @@ func functionRefFromV1Metadata(m *v1.Metadata, nameRemap map[string]string) *fis
} }
} }
func tprMetadataFromV1Metadata(m *v1.Metadata, nameRemap map[string]string) *api.ObjectMeta { func crdMetadataFromV1Metadata(m *v1.Metadata, nameRemap map[string]string) *metav1.ObjectMeta {
return &api.ObjectMeta{ return &metav1.ObjectMeta{
Name: nameRemap[m.Name], Name: nameRemap[m.Name],
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
} }
} }
@@ -298,20 +298,20 @@ func upgradeRestoreState(c *cli.Context) error {
pkgSpec := fission.PackageSpec{ pkgSpec := fission.PackageSpec{
Environment: fission.EnvironmentReference{ Environment: fission.EnvironmentReference{
Name: v1state.NameChanges[f.Environment.Name], Name: v1state.NameChanges[f.Environment.Name],
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Deployment: *archive, Deployment: *archive,
} }
pkg, err := client.PackageCreate(&tpr.Package{ pkg, err := client.PackageCreate(&crd.Package{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: pkgName, Name: pkgName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: pkgSpec, Spec: pkgSpec,
}) })
checkErr(err, fmt.Sprintf("create package %v", pkgName)) checkErr(err, fmt.Sprintf("create package %v", pkgName))
_, err = client.FunctionCreate(&tpr.Function{ _, err = client.FunctionCreate(&crd.Function{
Metadata: *tprMetadataFromV1Metadata(&f.Metadata, v1state.NameChanges), Metadata: *crdMetadataFromV1Metadata(&f.Metadata, v1state.NameChanges),
Spec: fission.FunctionSpec{ Spec: fission.FunctionSpec{
Environment: pkgSpec.Environment, Environment: pkgSpec.Environment,
Package: fission.FunctionPackageRef{ Package: fission.FunctionPackageRef{
@@ -329,8 +329,8 @@ func upgradeRestoreState(c *cli.Context) error {
// create envs // create envs
for _, e := range v1state.Environments { for _, e := range v1state.Environments {
_, err = client.EnvironmentCreate(&tpr.Environment{ _, err = client.EnvironmentCreate(&crd.Environment{
Metadata: *tprMetadataFromV1Metadata(&e.Metadata, v1state.NameChanges), Metadata: *crdMetadataFromV1Metadata(&e.Metadata, v1state.NameChanges),
Spec: fission.EnvironmentSpec{ Spec: fission.EnvironmentSpec{
Version: 1, Version: 1,
Runtime: fission.Runtime{ Runtime: fission.Runtime{
@@ -342,9 +342,9 @@ func upgradeRestoreState(c *cli.Context) error {
} }
// create httptriggers // create httptriggers
for _, t := range v1state.Httptriggers { for _, t := range v1state.HTTPTriggers {
_, err = client.HTTPTriggerCreate(&tpr.Httptrigger{ _, err = client.HTTPTriggerCreate(&crd.HTTPTrigger{
Metadata: *tprMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), Metadata: *crdMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges),
Spec: fission.HTTPTriggerSpec{ Spec: fission.HTTPTriggerSpec{
RelativeURL: t.UrlPattern, RelativeURL: t.UrlPattern,
Method: t.Method, Method: t.Method,
@@ -356,8 +356,8 @@ func upgradeRestoreState(c *cli.Context) error {
// create mqtriggers // create mqtriggers
for _, t := range v1state.Mqtriggers { for _, t := range v1state.Mqtriggers {
_, err = client.MessageQueueTriggerCreate(&tpr.Messagequeuetrigger{ _, err = client.MessageQueueTriggerCreate(&crd.MessageQueueTrigger{
Metadata: *tprMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), Metadata: *crdMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges),
Spec: fission.MessageQueueTriggerSpec{ Spec: fission.MessageQueueTriggerSpec{
FunctionReference: *functionRefFromV1Metadata(&t.Function, v1state.NameChanges), FunctionReference: *functionRefFromV1Metadata(&t.Function, v1state.NameChanges),
MessageQueueType: t.MessageQueueType, MessageQueueType: t.MessageQueueType,
@@ -369,9 +369,9 @@ func upgradeRestoreState(c *cli.Context) error {
} }
// create time triggers // create time triggers
for _, t := range v1state.Timetriggers { for _, t := range v1state.TimeTriggers {
_, err = client.TimeTriggerCreate(&tpr.Timetrigger{ _, err = client.TimeTriggerCreate(&crd.TimeTrigger{
Metadata: *tprMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), Metadata: *crdMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges),
Spec: fission.TimeTriggerSpec{ Spec: fission.TimeTriggerSpec{
FunctionReference: *functionRefFromV1Metadata(&t.Function, v1state.NameChanges), FunctionReference: *functionRefFromV1Metadata(&t.Function, v1state.NameChanges),
Cron: t.Cron, Cron: t.Cron,
@@ -382,8 +382,8 @@ func upgradeRestoreState(c *cli.Context) error {
// create watches // create watches
for _, t := range v1state.Watches { for _, t := range v1state.Watches {
_, err = client.WatchCreate(&tpr.Kuberneteswatchtrigger{ _, err = client.WatchCreate(&crd.KubernetesWatchTrigger{
Metadata: *tprMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), Metadata: *crdMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges),
Spec: fission.KubernetesWatchTriggerSpec{ Spec: fission.KubernetesWatchTriggerSpec{
Namespace: t.Namespace, Namespace: t.Namespace,
Type: t.ObjType, Type: t.ObjType,
+7 -7
View File
@@ -23,10 +23,10 @@ import (
"github.com/satori/go.uuid" "github.com/satori/go.uuid"
"github.com/urfave/cli" "github.com/urfave/cli"
"k8s.io/client-go/1.5/pkg/api" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
func wCreate(c *cli.Context) error { func wCreate(c *cli.Context) error {
@@ -61,10 +61,10 @@ func wCreate(c *cli.Context) error {
// automatically name watches // automatically name watches
watchName := uuid.NewV4().String() watchName := uuid.NewV4().String()
w := &tpr.Kuberneteswatchtrigger{ w := &crd.KubernetesWatchTrigger{
Metadata: api.ObjectMeta{ Metadata: metav1.ObjectMeta{
Name: watchName, Name: watchName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: fission.KubernetesWatchTriggerSpec{ Spec: fission.KubernetesWatchTriggerSpec{
Namespace: namespace, Namespace: namespace,
@@ -104,9 +104,9 @@ func wDelete(c *cli.Context) error {
fatal("Need name of watch to delete, use --name") fatal("Need name of watch to delete, use --name")
} }
err := client.WatchDelete(&api.ObjectMeta{ err := client.WatchDelete(&metav1.ObjectMeta{
Name: wName, Name: wName,
Namespace: api.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}) })
checkErr(err, "delete watch") checkErr(err, "delete watch")
Generated
+208 -175
View File
@@ -1,44 +1,39 @@
hash: 2703407b4ae6e28cd146b14ff6b77175a17f0f944f7d75131ac0fa0406793d5b hash: 7c938e591b0602b9fd3412aeffd3f1438fc77eaea80c8d9dd03431adb0e1e1c9
updated: 2017-08-27T22:38:51.57334855+08:00 updated: 2017-11-01T16:18:51.144141389+08:00
imports: imports:
- name: github.com/blang/semver - name: cloud.google.com/go
version: 60ec3488bfea7cca02b021d106d9911120d25fe9 version: 3b1ae45394a234c385be014e9a488f2bb6eef821
subpackages:
- compute/metadata
- internal
- name: github.com/Azure/go-autorest
version: 58f6f26e200fa5dfb40c9cd1c83f3e2c860d779d
subpackages:
- autorest
- autorest/adal
- autorest/azure
- autorest/date
- name: github.com/coreos/etcd - name: github.com/coreos/etcd
version: 952eb4fadeef3f840bd7557544338c985d4ed0ef version: 3ac54be402ffe4e6df505814456d4931508aaf21
subpackages: subpackages:
- client - client
- pkg/pathutil
- pkg/types
- name: github.com/coreos/go-oidc
version: 16c5ecc505f1efa0fe4685826fd9962c4d137e87
subpackages:
- http
- jose
- key
- oauth2
- oidc
- name: github.com/coreos/pkg
version: fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8
subpackages:
- capnslog
- health
- httputil
- timeutil
- name: github.com/davecgh/go-spew - name: github.com/davecgh/go-spew
version: 346938d642f2ec3594ed81d874461961cd0faa76 version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
subpackages: subpackages:
- spew - spew
- name: github.com/dchest/uniuri - name: github.com/dchest/uniuri
version: 8902c56451e9b58ff940bbe5fec35d5f9c04584a version: 8902c56451e9b58ff940bbe5fec35d5f9c04584a
- name: github.com/dgrijalva/jwt-go
version: 01aeca54ebda6e0fbfafd0a524d234159c05ec20
- name: github.com/docker/distribution - name: github.com/docker/distribution
version: 6e62b398420f8c0444e34e8a69a350c139f65956 version: cd27f179f2c10c5d300e6d09025b538c475b0d51
subpackages: subpackages:
- digest - digest
- reference - reference
- name: github.com/docopt/docopt-go - name: github.com/docopt/docopt-go
version: 784ddc588536785e7299f7272f39101f7faccc3f version: 784ddc588536785e7299f7272f39101f7faccc3f
- name: github.com/dsnet/compress - name: github.com/dsnet/compress
version: 0ae8e136a5df9e3caf6c0f69983608b07438411b version: c4dbed65594871659ea7347a85e1b8dcd97b9990
subpackages: subpackages:
- bzip2 - bzip2
- bzip2/internal/sais - bzip2/internal/sais
@@ -46,70 +41,78 @@ imports:
- internal/errors - internal/errors
- internal/prefix - internal/prefix
- name: github.com/emicklei/go-restful - name: github.com/emicklei/go-restful
version: 3d66f886316ac990eb502aaa89ea38546420b8b7 version: ff4f55a206334ef123e4f79bbf348980da81ca46
subpackages: subpackages:
- log - log
- swagger - name: github.com/emicklei/go-restful-swagger12
version: dcef7f55730566d41eae5db10e7d6981829720f6
- name: github.com/ghodss/yaml - name: github.com/ghodss/yaml
version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee
- name: github.com/go-openapi/analysis
version: b44dc874b601d9e4e2f6e19140e794ba24bead3b
- name: github.com/go-openapi/jsonpointer - name: github.com/go-openapi/jsonpointer
version: 8d96a2dc61536b690bd36b2e9df0b3c0b62825b2 version: 46af16f9f7b149af66e5d1bd010e3574dc06de98
- name: github.com/go-openapi/jsonreference - name: github.com/go-openapi/jsonreference
version: 36d33bfe519efae5632669801b180bf1a245da3b version: 13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272
- name: github.com/go-openapi/loads
version: 18441dfa706d924a39a030ee2c3b1d8d81917b38
- name: github.com/go-openapi/spec - name: github.com/go-openapi/spec
version: d1c18b339aece4b16ead6d253b85b6ad7180ea54 version: 6aced65f8501fe1217321abf0749d354824ba2ff
- name: github.com/go-openapi/swag - name: github.com/go-openapi/swag
version: 3b6d86cd965820f968760d5d419cb4add096bdd7 version: 1d0bd113de87027671077d3c71eb3ac5d7dbba72
- name: github.com/gogo/protobuf - name: github.com/gogo/protobuf
version: 8d70fb3182befc465c4a1eac8ad4d38ff49778e2 version: c0656edd0d9eab7c66d1eb0c568f9039345796f7
subpackages: subpackages:
- gogoproto
- proto - proto
- protoc-gen-gogo/descriptor
- sortkeys - sortkeys
- name: github.com/golang/glog - name: github.com/golang/glog
version: 23def4e6c14b4da8ac2ed8007337bc5eb5007998 version: 44145f04b68cf362d9c4df2182967c2275eaefed
- name: github.com/golang/protobuf - name: github.com/golang/protobuf
version: 4bd1920723d7b7c925de087aa32e2187708897f7 version: 4bd1920723d7b7c925de087aa32e2187708897f7
subpackages: subpackages:
- jsonpb
- proto - proto
- name: github.com/golang/snappy - name: github.com/golang/snappy
version: 553a641470496b2327abcac10b36396bd98e45c9 version: 553a641470496b2327abcac10b36396bd98e45c9
- name: github.com/google/gofuzz - name: github.com/google/gofuzz
version: fd52762d25a41827db7ef64c43756fd4b9f7e382 version: 44d81051d367757e1c7c6a5a86423ece9afcf63c
- name: github.com/gorilla/context - name: github.com/gorilla/context
version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42
- name: github.com/gorilla/handlers - name: github.com/gorilla/handlers
version: 3a5767ca75ece5f7f1440b1d16975247f8d8b221 version: a4043c62cc2329bacda331d33fc908ab11ef0ec3
- name: github.com/gorilla/mux - name: github.com/gorilla/mux
version: 392c28fe23e1c45ddba891b0320b3b5df220beea version: 24fca303ac6da784b9e8269f724ddeb0b2eea5e7
- name: github.com/graymeta/stow
version: 1c51f76db54d79c9db24cb131011632eb586196c
subpackages:
- local
- name: github.com/hashicorp/golang-lru
version: a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4
subpackages:
- simplelru
- name: github.com/howeyc/gopass - name: github.com/howeyc/gopass
version: bf9dde6d0d2c004a008c27aaee91170c786f6db8 version: bf9dde6d0d2c004a008c27aaee91170c786f6db8
- name: github.com/imdario/mergo - name: github.com/imdario/mergo
version: e3000cb3d28c72b837601cac94debd91032d19fe version: 6633656539c1639d9d78127b7d47c622b5d7b6dc
- name: github.com/influxdata/influxdb - name: github.com/influxdata/influxdb
version: b7bb7e8359642b6e071735b50ae41f5eb343fd42 version: b7bb7e8359642b6e071735b50ae41f5eb343fd42
subpackages: subpackages:
- client/v2 - client/v2
- models - models
- pkg/escape - pkg/escape
- name: github.com/graymeta/stow
version: da285caa6daa337ae04a9ac603dbaf9009ffe687
subpackages:
- local
- name: github.com/jonboulle/clockwork
version: 2eee05ed794112d45db504eb05aa693efd2b8b09
- name: github.com/juju/ratelimit - name: github.com/juju/ratelimit
version: 77ed1c8a01217656d2080ad51981f6e99adaa177 version: 5b9ff866471762aa2ab2dced63c9fb6f53921342
- name: github.com/mailru/easyjson - name: github.com/mailru/easyjson
version: 159cdb893c982e3d1bc6450322fedd514f9c9de3 version: d5b7844b561a7bc640052f1b935f7b800330d7e0
subpackages: subpackages:
- buffer - buffer
- jlexer - jlexer
- jwriter - jwriter
- name: github.com/mholt/archiver - name: github.com/mholt/archiver
version: fe92d3d85a514d2752ad3b61ec412b598a2754f9 version: 26cf5bb32d07aa4e8d0de15f56ce516f4641d7df
- name: github.com/nats-io/go-nats - name: github.com/nats-io/go-nats
version: 6949c8e06a246e4177961aab22940b5c411e48f0 version: 9147cfac69833916f9c73353ba43f939815c330a
subpackages: subpackages:
- encoders/builtin - encoders/builtin
- util - util
@@ -118,17 +121,15 @@ imports:
subpackages: subpackages:
- pb - pb
- name: github.com/nats-io/nats-streaming-server - name: github.com/nats-io/nats-streaming-server
version: 7a922646104d066c98527959455993231fadd168 version: 9ebc07951af540e177f6a5bb0424f716fd867074
subpackages: subpackages:
- util - util
- name: github.com/nats-io/nuid - name: github.com/nats-io/nuid
version: 289cccf02c178dc782430d534e3c1f5b72af807f version: 289cccf02c178dc782430d534e3c1f5b72af807f
- name: github.com/nwaples/rardecode - name: github.com/nwaples/rardecode
version: f22b7ef81a0afac9ce1447d37e5ab8e99fbd2f73 version: e06696f847aeda6f39a8f0b7cdff193b7690aef6
- name: github.com/pborman/uuid
version: 3d4f2ba23642d3cfd06bd4b54cf03d99d95c0f1b
- name: github.com/pierrec/lz4 - name: github.com/pierrec/lz4
version: 5a3d2245f97fc249850e7802e3c01fad02a1c316 version: 08c27939df1bd95e881e2c2367a749964ad1fceb
- name: github.com/pierrec/xxHash - name: github.com/pierrec/xxHash
version: a0006b13c722f7f12368c00a3d3c2ae8a999a0c6 version: a0006b13c722f7f12368c00a3d3c2ae8a999a0c6
subpackages: subpackages:
@@ -138,15 +139,15 @@ imports:
- name: github.com/PuerkitoBio/urlesc - name: github.com/PuerkitoBio/urlesc
version: 5bd2802263f21d8788851d5305584c82a5c75d7e version: 5bd2802263f21d8788851d5305584c82a5c75d7e
- name: github.com/robfig/cron - name: github.com/robfig/cron
version: df38d32658d8788cd446ba74db4bb5375c4b0cb3 version: 736158dc09e10f1911ca3a1e1b01f11b566ce5db
- name: github.com/satori/go.uuid - name: github.com/satori/go.uuid
version: 879c5887cd475cd7864858769793b2ceb0d44feb version: 879c5887cd475cd7864858769793b2ceb0d44feb
- name: github.com/sirupsen/logrus - name: github.com/sirupsen/logrus
version: ba1b36c82c5e05c4f912a88eab0dcd91a171688f version: 68cec9f21fbf3ea8d8f98c044bc6ce05f17b267a
- name: github.com/spf13/pflag - name: github.com/spf13/pflag
version: 08b1a584251b5b62f458943640fc8ebd4d50aaa5 version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7
- name: github.com/ugorji/go - name: github.com/ugorji/go
version: f1f1a805ed361a0e078bb537e4ea78cd37dcf065 version: ded73eae5db7e7a0ef6f55aace87a2873c5d2b74
subpackages: subpackages:
- codec - codec
- name: github.com/ulikunitz/xz - name: github.com/ulikunitz/xz
@@ -156,34 +157,35 @@ imports:
- internal/xlog - internal/xlog
- lzma - lzma
- name: github.com/urfave/cli - name: github.com/urfave/cli
version: 0bdeddeeb0f650497d603c4ad7b20cfe685682f6 version: cfb38830724cc34fedffe9a2a29fb54fa9169cd1
- name: golang.org/x/crypto - name: golang.org/x/crypto
version: 9477e0b78b9ac3d0b03822fd95422e2fe07627cd version: d172538b2cfce0c13cee31e647d0367aa8cd2486
subpackages: subpackages:
- ssh/terminal - ssh/terminal
- name: golang.org/x/net - name: golang.org/x/net
version: 6acef71eb69611914f7a30939ea9f6e194c78172 version: f2499483f923065a842d38eb4c7f1927e6fc6e6d
subpackages: subpackages:
- context - context
- context/ctxhttp
- http2 - http2
- http2/hpack - http2/hpack
- idna - idna
- lex/httplex
- name: golang.org/x/oauth2 - name: golang.org/x/oauth2
version: 045497edb6234273d67dbc25da3f2ddbc4c4cacf version: a6bd8cefa1811bd24b86f8902872e4e8225f74c4
subpackages: subpackages:
- google - google
- internal - internal
- jws - jws
- jwt - jwt
- name: golang.org/x/sys - name: golang.org/x/sys
version: b699b7032584f0953262cb2788a0ca19bb494703 version: 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9
subpackages: subpackages:
- unix - unix
- name: golang.org/x/text - name: golang.org/x/text
version: a263ba8db058568bb9beba166777d9c9dbe75d68 version: 2910a502d2bf9e43193af9d68ca516529614eed3
subpackages: subpackages:
- cases - cases
- internal
- internal/tag - internal/tag
- language - language
- runes - runes
@@ -205,120 +207,151 @@ imports:
- internal/remote_api - internal/remote_api
- internal/urlfetch - internal/urlfetch
- urlfetch - urlfetch
- name: google.golang.org/cloud
version: 975617b05ea8a58727e6c1a06b6161ff4185a9f2
subpackages:
- compute/metadata
- internal
- internal/opts
- storage
- name: gopkg.in/inf.v0 - name: gopkg.in/inf.v0
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
- name: gopkg.in/yaml.v2 - name: gopkg.in/yaml.v2
version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 version: 53feefa2559fb8dfa8d81baad31be332c97d6c77
- name: k8s.io/client-go - name: k8s.io/api
version: 843f7c4f28b1f647f664f883697107d5c02c5acc version: 4b8fc5be9b77d91bbb6525d18591c43699a2b4e5
- name: k8s.io/apiextensions-apiserver
version: fcd622fe88a4a6efcb5aea9e94ee87324ac1b036
subpackages: subpackages:
- 1.5/discovery - pkg/apis/apiextensions
- 1.5/kubernetes - pkg/apis/apiextensions/v1beta1
- 1.5/kubernetes/typed/apps/v1alpha1 - pkg/client/clientset/clientset
- 1.5/kubernetes/typed/authentication/v1beta1 - pkg/client/clientset/clientset/scheme
- 1.5/kubernetes/typed/authorization/v1beta1 - pkg/client/clientset/clientset/typed/apiextensions/v1beta1
- 1.5/kubernetes/typed/autoscaling/v1 - name: k8s.io/apimachinery
- 1.5/kubernetes/typed/batch/v1 version: 8ab5f3d8a330c2e9baaf84e39042db8d49034ae2
- 1.5/kubernetes/typed/certificates/v1alpha1 subpackages:
- 1.5/kubernetes/typed/core/v1 - pkg/api/equality
- 1.5/kubernetes/typed/extensions/v1beta1 - pkg/api/errors
- 1.5/kubernetes/typed/policy/v1alpha1 - pkg/api/meta
- 1.5/kubernetes/typed/rbac/v1alpha1 - pkg/api/resource
- 1.5/kubernetes/typed/storage/v1beta1 - pkg/apimachinery
- 1.5/pkg/api - pkg/apimachinery/announced
- 1.5/pkg/api/errors - pkg/apimachinery/registered
- 1.5/pkg/api/install - pkg/apis/meta/v1
- 1.5/pkg/api/meta - pkg/apis/meta/v1/unstructured
- 1.5/pkg/api/meta/metatypes - pkg/apis/meta/v1alpha1
- 1.5/pkg/api/resource - pkg/conversion
- 1.5/pkg/api/unversioned - pkg/conversion/queryparams
- 1.5/pkg/api/v1 - pkg/conversion/unstructured
- 1.5/pkg/api/validation/path - pkg/fields
- 1.5/pkg/apimachinery - pkg/labels
- 1.5/pkg/apimachinery/announced - pkg/openapi
- 1.5/pkg/apimachinery/registered - pkg/runtime
- 1.5/pkg/apis/apps - pkg/runtime/schema
- 1.5/pkg/apis/apps/install - pkg/runtime/serializer
- 1.5/pkg/apis/apps/v1alpha1 - pkg/runtime/serializer/json
- 1.5/pkg/apis/authentication - pkg/runtime/serializer/protobuf
- 1.5/pkg/apis/authentication/install - pkg/runtime/serializer/recognizer
- 1.5/pkg/apis/authentication/v1beta1 - pkg/runtime/serializer/streaming
- 1.5/pkg/apis/authorization - pkg/runtime/serializer/versioning
- 1.5/pkg/apis/authorization/install - pkg/selection
- 1.5/pkg/apis/authorization/v1beta1 - pkg/types
- 1.5/pkg/apis/autoscaling - pkg/util/cache
- 1.5/pkg/apis/autoscaling/install - pkg/util/clock
- 1.5/pkg/apis/autoscaling/v1 - pkg/util/diff
- 1.5/pkg/apis/batch - pkg/util/errors
- 1.5/pkg/apis/batch/install - pkg/util/framer
- 1.5/pkg/apis/batch/v1 - pkg/util/intstr
- 1.5/pkg/apis/batch/v2alpha1 - pkg/util/json
- 1.5/pkg/apis/certificates - pkg/util/net
- 1.5/pkg/apis/certificates/install - pkg/util/rand
- 1.5/pkg/apis/certificates/v1alpha1 - pkg/util/runtime
- 1.5/pkg/apis/extensions - pkg/util/sets
- 1.5/pkg/apis/extensions/install - pkg/util/validation
- 1.5/pkg/apis/extensions/v1beta1 - pkg/util/validation/field
- 1.5/pkg/apis/policy - pkg/util/wait
- 1.5/pkg/apis/policy/install - pkg/util/yaml
- 1.5/pkg/apis/policy/v1alpha1 - pkg/version
- 1.5/pkg/apis/rbac - pkg/watch
- 1.5/pkg/apis/rbac/install - third_party/forked/golang/reflect
- 1.5/pkg/apis/rbac/v1alpha1 - name: k8s.io/client-go
- 1.5/pkg/apis/storage version: d92e8497f71b7b4e0494e5bd204b48d34bd6f254
- 1.5/pkg/apis/storage/install subpackages:
- 1.5/pkg/apis/storage/v1beta1 - discovery
- 1.5/pkg/auth/user - kubernetes
- 1.5/pkg/conversion - kubernetes/scheme
- 1.5/pkg/conversion/queryparams - kubernetes/typed/admissionregistration/v1alpha1
- 1.5/pkg/fields - kubernetes/typed/apps/v1beta1
- 1.5/pkg/genericapiserver/openapi/common - kubernetes/typed/authentication/v1
- 1.5/pkg/labels - kubernetes/typed/authentication/v1beta1
- 1.5/pkg/runtime - kubernetes/typed/authorization/v1
- 1.5/pkg/runtime/serializer - kubernetes/typed/authorization/v1beta1
- 1.5/pkg/runtime/serializer/json - kubernetes/typed/autoscaling/v1
- 1.5/pkg/runtime/serializer/protobuf - kubernetes/typed/autoscaling/v2alpha1
- 1.5/pkg/runtime/serializer/recognizer - kubernetes/typed/batch/v1
- 1.5/pkg/runtime/serializer/streaming - kubernetes/typed/batch/v2alpha1
- 1.5/pkg/runtime/serializer/versioning - kubernetes/typed/certificates/v1beta1
- 1.5/pkg/selection - kubernetes/typed/core/v1
- 1.5/pkg/third_party/forked/golang/reflect - kubernetes/typed/extensions/v1beta1
- 1.5/pkg/types - kubernetes/typed/networking/v1
- 1.5/pkg/util - kubernetes/typed/policy/v1beta1
- 1.5/pkg/util/cert - kubernetes/typed/rbac/v1alpha1
- 1.5/pkg/util/clock - kubernetes/typed/rbac/v1beta1
- 1.5/pkg/util/errors - kubernetes/typed/settings/v1alpha1
- 1.5/pkg/util/flowcontrol - kubernetes/typed/storage/v1
- 1.5/pkg/util/framer - kubernetes/typed/storage/v1beta1
- 1.5/pkg/util/integer - pkg/api
- 1.5/pkg/util/intstr - pkg/api/v1
- 1.5/pkg/util/json - pkg/api/v1/ref
- 1.5/pkg/util/labels - pkg/apis/admissionregistration
- 1.5/pkg/util/net - pkg/apis/admissionregistration/v1alpha1
- 1.5/pkg/util/parsers - pkg/apis/apps
- 1.5/pkg/util/rand - pkg/apis/apps/v1beta1
- 1.5/pkg/util/runtime - pkg/apis/authentication
- 1.5/pkg/util/sets - pkg/apis/authentication/v1
- 1.5/pkg/util/uuid - pkg/apis/authentication/v1beta1
- 1.5/pkg/util/validation - pkg/apis/authorization
- 1.5/pkg/util/validation/field - pkg/apis/authorization/v1
- 1.5/pkg/util/wait - pkg/apis/authorization/v1beta1
- 1.5/pkg/util/yaml - pkg/apis/autoscaling
- 1.5/pkg/version - pkg/apis/autoscaling/v1
- 1.5/pkg/watch - pkg/apis/autoscaling/v2alpha1
- 1.5/pkg/watch/versioned - pkg/apis/batch
- 1.5/plugin/pkg/client/auth - pkg/apis/batch/v1
- 1.5/plugin/pkg/client/auth/gcp - pkg/apis/batch/v2alpha1
- 1.5/plugin/pkg/client/auth/oidc - pkg/apis/certificates
- 1.5/rest - pkg/apis/certificates/v1beta1
- 1.5/tools/clientcmd/api - pkg/apis/extensions
- 1.5/tools/metrics - pkg/apis/extensions/v1beta1
- 1.5/transport - pkg/apis/networking
- pkg/apis/networking/v1
- pkg/apis/policy
- pkg/apis/policy/v1beta1
- pkg/apis/rbac
- pkg/apis/rbac/v1alpha1
- pkg/apis/rbac/v1beta1
- pkg/apis/settings
- pkg/apis/settings/v1alpha1
- pkg/apis/storage
- pkg/apis/storage/v1
- pkg/apis/storage/v1beta1
- pkg/labels
- pkg/util
- pkg/util/intstr
- pkg/util/parsers
- pkg/version
- plugin/pkg/client/auth
- plugin/pkg/client/auth/azure
- plugin/pkg/client/auth/gcp
- plugin/pkg/client/auth/oidc
- rest
- rest/watch
- third_party/forked/golang/template
- tools/auth
- tools/cache
- tools/clientcmd
- tools/clientcmd/api
- tools/clientcmd/api/latest
- tools/clientcmd/api/v1
- tools/metrics
- transport
- util/cert
- util/flowcontrol
- util/homedir
- util/integer
- util/jsonpath
testImports: [] testImports: []
+16 -8
View File
@@ -20,15 +20,23 @@ import:
subpackages: subpackages:
- context - context
- package: k8s.io/client-go - package: k8s.io/client-go
version: v1.5.0 version: v4.0.0
subpackages: subpackages:
- 1.5/kubernetes - kubernetes
- 1.5/pkg/api - pkg/api
- 1.5/pkg/api/v1 - pkg/api/v1
- 1.5/pkg/apis/extensions/v1beta1 - pkg/apis/extensions/v1beta1
- 1.5/pkg/labels - pkg/labels
- 1.5/pkg/util/intstr - pkg/util/intstr
- 1.5/rest - rest
- package: k8s.io/api
version: 4b8fc5be9b77d91bbb6525d18591c43699a2b4e5
- package: k8s.io/apiextensions-apiserver
version: release-1.7
subpackages:
- pkg/apis/apiextensions/v1beta1
- package: k8s.io/apimachinery
version: release-1.7
- package: github.com/influxdata/influxdb - package: github.com/influxdata/influxdb
version: v1.2.0 version: v1.2.0
subpackages: subpackages:
+32 -17
View File
@@ -96,17 +96,29 @@ push_fetcher_image() {
build_and_push_env_image() { build_and_push_env_image() {
version=$1 version=$1
envdir=$2 envdir=$2
imgname=$3 imgnamebase=$3
imgvariant=$4
echo "Building $envdir -> $imgname:$version" if [ -z "$imgvariant" ]
then
# no variant specified, just use the base name
imgname=$imgnamebase
dockerfile="Dockerfile"
else
# variant specified - append variant to image name and assume dockerfile
# exists with same suffix (e.g. image node-env-debian built from Dockerfile-debian)
imgname="$imgname-$imgvariant"
dockerfile="Dockerfile-$imgvariant"
fi
echo "Building $envdir -> $imgname:$version using $dockerfile"
pushd $DIR/environments/$envdir pushd $DIR/environments/$envdir
if [ -f build.sh ] if [ -f build.sh ]
then then
./build.sh ./build.sh
fi fi
docker build -t fission/$imgname:$version . docker build -t fission/$imgname:$version -f $dockerfile .
docker tag fission/$imgname:$version fission/$imgname:latest docker tag fission/$imgname:$version fission/$imgname:latest
docker push fission/$imgname:$version docker push fission/$imgname:$version
docker push fission/$imgname:latest docker push fission/$imgname:latest
popd popd
@@ -115,26 +127,29 @@ build_and_push_env_image() {
build_and_push_all_envs() { build_and_push_all_envs() {
version=$1 version=$1
build_and_push_env_image $version nodejs node-env # call with version, env dir, image name base, image name variant
build_and_push_env_image $version binary binary-env build_and_push_env_image "$version" "nodejs" "node-env" ""
build_and_push_env_image $version dotnet dotnet-env build_and_push_env_image "$version" "nodejs" "node-env" "debian"
build_and_push_env_image $version dotnet20 dotnet20-env build_and_push_env_image "$version" "binary" "binary-env" ""
build_and_push_env_image $version go go-env build_and_push_env_image "$version" "dotnet" "dotnet-env" ""
build_and_push_env_image $version perl perl-env build_and_push_env_image "$version" "dotnet20" "dotnet20-env" ""
build_and_push_env_image $version php7 php-env build_and_push_env_image "$version" "go" "go-env" ""
build_and_push_env_image $version python3 python-env build_and_push_env_image "$version" "perl" "perl-env" ""
build_and_push_env_image $version ruby ruby-env build_and_push_env_image "$version" "php7" "php-env" ""
build_and_push_env_image "$version" "python" "python-env" ""
build_and_push_env_image "$version" "python" "python-env" "2.7"
build_and_push_env_image "$version" "ruby" "ruby-env" ""
} }
build_charts() { build_charts() {
version=$1 version=$1
mkdir -p $BUILDDIR/charts mkdir -p $BUILDDIR/charts
pushd $DIR/charts pushd $DIR/charts
for c in all core find . -iname *.~?~ | xargs rm
for c in fission-all fission-core
do do
tgz=fission-$c-$version.tgz helm package $c/
tar czvf $tgz fission-$c/ mv *.tgz $BUILDDIR/charts/
mv $tgz $BUILDDIR/charts/
done done
popd popd
} }
+8 -4
View File
@@ -5,12 +5,16 @@ if [ ! -f ${KUBECONFIG} ]
then then
unset KUBECONFIG unset KUBECONFIG
else else
K="kubectl --kubeconfig $KUBECONFIG" K="kubectl --kubeconfig $KUBECONFIG --namespace default"
if $K get configmap ok-to-destroy if $K get configmap ok-to-destroy
then then
$K get function.fission.io -o name | cut -f2 -d'/' | xargs $K delete function.fission.io $K delete functions --all
$K get environment.fission.io -o name | cut -f2 -d'/' | xargs $K delete environment.fission.io $K delete environments --all
$K get httptrigger.fission.io -o name | cut -f2 -d'/' | xargs $K delete httptrigger.fission.io $K delete httptriggers --all
$K delete kuberneteswatchtriggers --all
$K delete messagequeuetriggers --all
$K delete packages --all
$K delete timetriggers --all
fi fi
fi fi
+24 -25
View File
@@ -19,7 +19,6 @@ package kubewatcher
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"log" "log"
@@ -28,17 +27,17 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"k8s.io/client-go/1.5/kubernetes" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/client-go/1.5/pkg/api" "k8s.io/apimachinery/pkg/api/meta"
apierrs "k8s.io/client-go/1.5/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/1.5/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/1.5/pkg/runtime" "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/1.5/pkg/types" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/1.5/pkg/watch" "k8s.io/client-go/kubernetes"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/crd"
"github.com/fission/fission/publisher" "github.com/fission/fission/publisher"
"github.com/fission/fission/tpr"
) )
type requestType int type requestType int
@@ -57,7 +56,7 @@ type (
} }
watchSubscription struct { watchSubscription struct {
watch tpr.Kuberneteswatchtrigger watch crd.KubernetesWatchTrigger
kubeWatch watch.Interface kubeWatch watch.Interface
lastResourceVersion string lastResourceVersion string
stopped *int32 stopped *int32
@@ -67,7 +66,7 @@ type (
kubeWatcherRequest struct { kubeWatcherRequest struct {
requestType requestType
watches []tpr.Kuberneteswatchtrigger watches []crd.KubernetesWatchTrigger
responseChannel chan *kubeWatcherResponse responseChannel chan *kubeWatcherResponse
} }
kubeWatcherResponse struct { kubeWatcherResponse struct {
@@ -86,7 +85,7 @@ func MakeKubeWatcher(kubernetesClient *kubernetes.Clientset, publisher publisher
return kw return kw
} }
func (kw *KubeWatcher) Sync(watches []tpr.Kuberneteswatchtrigger) error { func (kw *KubeWatcher) Sync(watches []crd.KubernetesWatchTrigger) error {
req := &kubeWatcherRequest{ req := &kubeWatcherRequest{
requestType: SYNC, requestType: SYNC,
watches: watches, watches: watches,
@@ -146,13 +145,13 @@ func printKubernetesObject(obj runtime.Object, w io.Writer) error {
return err return err
} }
func createKubernetesWatch(kubeClient *kubernetes.Clientset, w *tpr.Kuberneteswatchtrigger, resourceVersion string) (watch.Interface, error) { func createKubernetesWatch(kubeClient *kubernetes.Clientset, w *crd.KubernetesWatchTrigger, resourceVersion string) (watch.Interface, error) {
var wi watch.Interface var wi watch.Interface
var err error var err error
var watchTimeoutSec int64 = 120 var watchTimeoutSec int64 = 120
// TODO populate labelselector and fieldselector // TODO populate labelselector and fieldselector
listOptions := api.ListOptions{ listOptions := metav1.ListOptions{
ResourceVersion: resourceVersion, ResourceVersion: resourceVersion,
TimeoutSeconds: &watchTimeoutSec, TimeoutSeconds: &watchTimeoutSec,
} }
@@ -160,22 +159,22 @@ func createKubernetesWatch(kubeClient *kubernetes.Clientset, w *tpr.Kuberneteswa
// TODO handle the full list of types // TODO handle the full list of types
switch strings.ToUpper(w.Spec.Type) { switch strings.ToUpper(w.Spec.Type) {
case "POD": case "POD":
wi, err = kubeClient.Core().Pods(w.Spec.Namespace).Watch(listOptions) wi, err = kubeClient.CoreV1().Pods(w.Spec.Namespace).Watch(listOptions)
case "SERVICE": case "SERVICE":
wi, err = kubeClient.Core().Services(w.Spec.Namespace).Watch(listOptions) wi, err = kubeClient.CoreV1().Services(w.Spec.Namespace).Watch(listOptions)
case "REPLICATIONCONTROLLER": case "REPLICATIONCONTROLLER":
wi, err = kubeClient.Core().ReplicationControllers(w.Spec.Namespace).Watch(listOptions) wi, err = kubeClient.CoreV1().ReplicationControllers(w.Spec.Namespace).Watch(listOptions)
case "JOB": case "JOB":
wi, err = kubeClient.Batch().Jobs(w.Spec.Namespace).Watch(listOptions) wi, err = kubeClient.BatchV1().Jobs(w.Spec.Namespace).Watch(listOptions)
default: default:
msg := fmt.Sprintf("Error: unknown obj type '%v'", w.Spec.Type) msg := fmt.Sprintf("Error: unknown obj type '%v'", w.Spec.Type)
log.Println(msg) log.Println(msg)
err = errors.New(msg) err = errors.NewBadRequest(msg)
} }
return wi, err return wi, err
} }
func (kw *KubeWatcher) addWatch(w *tpr.Kuberneteswatchtrigger) error { func (kw *KubeWatcher) addWatch(w *crd.KubernetesWatchTrigger) error {
log.Printf("Adding watch %v: %v", w.Metadata.Name, w.Spec.FunctionReference) log.Printf("Adding watch %v: %v", w.Metadata.Name, w.Spec.FunctionReference)
ws, err := MakeWatchSubscription(w, kw.kubernetesClient, kw.publisher) ws, err := MakeWatchSubscription(w, kw.kubernetesClient, kw.publisher)
if err != nil { if err != nil {
@@ -185,7 +184,7 @@ func (kw *KubeWatcher) addWatch(w *tpr.Kuberneteswatchtrigger) error {
return nil return nil
} }
func (kw *KubeWatcher) removeWatch(w *tpr.Kuberneteswatchtrigger) error { func (kw *KubeWatcher) removeWatch(w *crd.KubernetesWatchTrigger) error {
log.Printf("Removing watch %v: %v", w.Metadata.Name, w.Spec.FunctionReference) log.Printf("Removing watch %v: %v", w.Metadata.Name, w.Spec.FunctionReference)
ws, ok := kw.watches[w.Metadata.UID] ws, ok := kw.watches[w.Metadata.UID]
if !ok { if !ok {
@@ -212,7 +211,7 @@ func (kw *KubeWatcher) removeWatch(w *tpr.Kuberneteswatchtrigger) error {
// return nil // return nil
// } // }
func MakeWatchSubscription(w *tpr.Kuberneteswatchtrigger, kubeClient *kubernetes.Clientset, publisher publisher.Publisher) (*watchSubscription, error) { func MakeWatchSubscription(w *crd.KubernetesWatchTrigger, kubeClient *kubernetes.Clientset, publisher publisher.Publisher) (*watchSubscription, error) {
var stopped int32 = 0 var stopped int32 = 0
ws := &watchSubscription{ ws := &watchSubscription{
watch: *w, watch: *w,
@@ -253,11 +252,11 @@ func (ws *watchSubscription) restartWatch() error {
} }
func getResourceVersion(obj runtime.Object) (string, error) { func getResourceVersion(obj runtime.Object) (string, error) {
meta, err := meta.Accessor(obj) m, err := meta.Accessor(obj)
if err != nil { if err != nil {
return "", err return "", err
} }
return meta.GetResourceVersion(), nil return m.GetResourceVersion(), nil
} }
func (ws *watchSubscription) eventDispatchLoop() { func (ws *watchSubscription) eventDispatchLoop() {
@@ -288,7 +287,7 @@ func (ws *watchSubscription) eventDispatchLoop() {
} }
if ev.Type == watch.Error { if ev.Type == watch.Error {
e := apierrs.FromObject(ev.Object) e := errors.FromObject(ev.Object)
log.Println("Watch error, retrying in a second: %v", e) log.Println("Watch error, retrying in a second: %v", e)
// Start from the beginning to get around "too old resource version" // Start from the beginning to get around "too old resource version"
ws.lastResourceVersion = "" ws.lastResourceVersion = ""
+2 -2
View File
@@ -17,12 +17,12 @@ limitations under the License.
package kubewatcher package kubewatcher
import ( import (
"github.com/fission/fission/crd"
"github.com/fission/fission/publisher" "github.com/fission/fission/publisher"
"github.com/fission/fission/tpr"
) )
func Start(routerUrl string) error { func Start(routerUrl string) error {
fissionClient, kubeClient, err := tpr.MakeFissionClient() fissionClient, kubeClient, _, err := crd.MakeFissionClient()
if err != nil { if err != nil {
return err return err
} }
+5 -5
View File
@@ -20,19 +20,19 @@ import (
"log" "log"
"time" "time"
"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"
) )
type ( type (
WatchSync struct { WatchSync struct {
client *tpr.FissionClient client *crd.FissionClient
kubeWatcher *KubeWatcher kubeWatcher *KubeWatcher
} }
) )
func MakeWatchSync(client *tpr.FissionClient, kubeWatcher *KubeWatcher) *WatchSync { func MakeWatchSync(client *crd.FissionClient, kubeWatcher *KubeWatcher) *WatchSync {
ws := &WatchSync{ ws := &WatchSync{
client: client, client: client,
kubeWatcher: kubeWatcher, kubeWatcher: kubeWatcher,
@@ -44,7 +44,7 @@ func MakeWatchSync(client *tpr.FissionClient, kubeWatcher *KubeWatcher) *WatchSy
func (ws *WatchSync) syncSvc() { func (ws *WatchSync) syncSvc() {
// TODO watch instead of polling // TODO watch instead of polling
for { for {
watches, err := ws.client.Kuberneteswatchtriggers(api.NamespaceAll).List(api.ListOptions{}) watches, err := ws.client.KubernetesWatchTriggers(metav1.NamespaceAll).List(metav1.ListOptions{})
if err != nil { if err != nil {
log.Fatalf("Failed to get Kubernetes watch trigger list: %v", err) log.Fatalf("Failed to get Kubernetes watch trigger list: %v", err)
} }
+3 -1
View File
@@ -35,7 +35,7 @@ ENV DEBIAN_FRONTEND noninteractive
# Install build tools # Install build tools
RUN apt-get -qq update && \ RUN apt-get -qq update && \
apt-get install -y -qq curl ca-certificates gcc make bash sudo && \ apt-get install -y -qq curl ca-certificates gcc g++ make bash sudo && \
apt-get install -y -qq --reinstall lsb-base lsb-release && \ apt-get install -y -qq --reinstall lsb-base lsb-release && \
# Install logging agent and required gems # Install logging agent and required gems
/usr/bin/curl -sSL https://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh | sh && \ /usr/bin/curl -sSL https://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh | sh && \
@@ -45,6 +45,8 @@ RUN apt-get -qq update && \
td-agent-gem install --no-document fluent-plugin-google-cloud -v 0.5.2 && \ td-agent-gem install --no-document fluent-plugin-google-cloud -v 0.5.2 && \
td-agent-gem install --no-document fluent-plugin-detect-exceptions -v 0.0.4 && \ td-agent-gem install --no-document fluent-plugin-detect-exceptions -v 0.0.4 && \
td-agent-gem install --no-document fluent-plugin-influxdb && \ td-agent-gem install --no-document fluent-plugin-influxdb && \
td-agent-gem install --no-document fluent-plugin-kubernetes_metadata_filter && \
td-agent-gem install --no-document fluent-plugin-flatten-hash && \
# Remove build tools # Remove build tools
apt-get remove -y -qq gcc make && \ apt-get remove -y -qq gcc make && \
apt-get autoremove -y -qq && \ apt-get autoremove -y -qq && \
+18 -12
View File
@@ -6,24 +6,30 @@
type tail type tail
format json format json
time_key time time_key time
path /var/log/fission/*.log path "#{ENV['FLUENTD_PATH']}"
time_format %Y-%m-%dT%H:%M:%S.%NZ time_format %Y-%m-%dT%H:%M:%S.%NZ
tag fission.* tag fission.*
read_from_head true read_from_head true
refresh_interval 5 refresh_interval 5
</source> </source>
<filter fission.**>
type kubernetes_metadata
</filter>
<filter fission.**>
type flatten_hash
separator _
</filter>
<match fission.**> <match fission.**>
type record_reformer type record_reformer
enable_ruby false enable_ruby false
tag log tag log
<record> <record>
namespace ${tag_parts[4]} funcuid ${kubernetes_labels_functionUid}
pod ${tag_parts[5]} </record>
container ${tag_parts[6]}
funcname ${tag_parts[7]}
funcuid ${tag_parts[8]}
</record>
</match> </match>
<match **> <match **>
@@ -35,7 +41,7 @@
password "#{ENV['INFLUXDB_PASSWD']}" password "#{ENV['INFLUXDB_PASSWD']}"
use_ssl false use_ssl false
time_precision s time_precision s
tag_keys ["funcuid", "pod"] tag_keys ["funcuid"]
sequence_tag _seq sequence_tag _seq
buffer_type file buffer_type file
buffer_path /var/log/fission/fluentd.buffer buffer_path /var/log/fission/fluentd.buffer
-215
View File
@@ -1,215 +0,0 @@
/*
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 logger
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/fission/fission"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
"k8s.io/client-go/1.5/kubernetes"
"k8s.io/client-go/1.5/rest"
)
func makelogRequestTracker() logRequestTracker {
return logRequestTracker{
logMap: make(map[string]LogRequest),
}
}
func (l logRequestTracker) Add(logReq LogRequest) {
l.Lock()
l.logMap[logReq.Pod] = logReq
l.Unlock()
}
func (l logRequestTracker) Get(pod string) LogRequest {
l.RLock()
logReq, ok := l.logMap[pod]
l.RUnlock()
if ok {
return logReq
}
return LogRequest{}
}
func (l logRequestTracker) Remove(logReq LogRequest) {
l.Lock()
delete(l.logMap, logReq.Pod)
l.Unlock()
}
// Get a kubernetes client using the pod's service account. This only
// works when we're running inside a kubernetes cluster.
func getKubernetesClient() (*kubernetes.Clientset, error) {
// creates the in-cluster config
config, err := rest.InClusterConfig()
if err != nil {
log.Printf("Error getting kubernetes client config: %v", err)
return nil, err
}
// creates the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Printf("Error getting kubernetes client: %v", err)
return nil, err
}
return clientset, nil
}
// make sure that the targetPath is a legitimate path for security purpose
func validateFilePath(targetPath string, expectedPathPrefix string) bool {
targetPath = filepath.Clean(targetPath)
return strings.HasPrefix(targetPath, expectedPathPrefix)
}
// The ContainerID is consist of container engine type (docker://) and uuid of container.
// (e.g., docker://f4ca66baaa715030e20273aaf5232635a144165f1cd8e34ca5175064c245b679)
// This function tries to extract container uuid from ContainerID.
func parseContainerString(containerID string) (string, error) {
// Trim the quotes and split the type and ID.
parts := strings.Split(strings.Trim(containerID, "\""), "://")
if len(parts) != 2 {
return "", fmt.Errorf("invalid container ID: %q", containerID)
}
_, ID := parts[0], parts[1]
return ID, nil
}
func getcontainerID(kubeClient *kubernetes.Clientset, namespace, pod, container string) (string, error) {
podInfo, err := kubeClient.Core().Pods(namespace).Get(pod)
if err != nil {
log.Printf("Failed to get pod info: %v", err)
return "", err
}
var containerID string
for _, c := range podInfo.Status.ContainerStatuses {
if c.Name == container {
containerID, err = parseContainerString(c.ContainerID)
if err != nil {
log.Printf("Failed to get container id: %v", err)
return "", err
}
return containerID, nil
}
}
return "", fission.MakeError(404, "no matching container is found")
}
func getContainerLogPath(logReq LogRequest) (string, bool) {
logPath := fmt.Sprintf("/var/lib/docker/containers/%s/%s-json.log", logReq.ContainerID, logReq.ContainerID)
if !validateFilePath(logPath, "/var/lib/docker/containers") {
return "", false
}
return logPath, true
}
func getFissionLogSymlinkPath(logReq LogRequest) (string, bool) {
// pass function related information through a symlink name
logSymLink := fmt.Sprintf("/var/log/fission/%s.%s.%s.%s.%s.log", logReq.Namespace, logReq.Pod, logReq.ContainerID, logReq.FuncName, logReq.FuncUid)
if !validateFilePath(logSymLink, "/var/log/fission") {
return "", false
}
return logSymLink, true
}
func createLogSymlink(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Failed to read request", 500)
return
}
logReq := LogRequest{}
if err = json.Unmarshal(body, &logReq); err != nil {
w.Write([]byte(fmt.Sprintf("%v", err)))
return
}
kubernetesClient, err := getKubernetesClient()
if err != nil {
log.Warningf("Failed to get kubernetes client: %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
containerID, err := getcontainerID(kubernetesClient, logReq.Namespace, logReq.Pod, logReq.Container)
if err != nil || containerID == "" {
log.Warningf("Failed to get container id: %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
logReq.ContainerID = containerID
containerLogFilePath, isValidLogPath := getContainerLogPath(logReq)
fissionLogSymlinkPath, isValidSymlinkPath := getFissionLogSymlinkPath(logReq)
if !isValidLogPath || !isValidSymlinkPath {
w.WriteHeader(http.StatusBadRequest)
return
}
err = os.Symlink(containerLogFilePath, fissionLogSymlinkPath)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
logInfo.Add(logReq)
w.WriteHeader(http.StatusOK)
}
func removeLogSymlink(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
pod := vars["pod"]
logReq := logInfo.Get(pod)
if logReq.Pod == "" {
w.WriteHeader(http.StatusInternalServerError)
return
}
fissionLogSymlinkPath, isValidSymlinkPath := getFissionLogSymlinkPath(logReq)
if !isValidSymlinkPath {
w.WriteHeader(http.StatusBadRequest)
return
}
err := os.Remove(fissionLogSymlinkPath)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
}
var logInfo logRequestTracker
func Start() {
logInfo = makelogRequestTracker()
r := mux.NewRouter()
r.HandleFunc("/v1/log", createLogSymlink).Methods("POST")
r.HandleFunc("/v1/log/{pod}", removeLogSymlink).Methods("DELETE")
address := fmt.Sprintf(":%v", 1234)
log.Printf("starting logger at port %s", address)
log.Fatal(http.ListenAndServe(address, handlers.LoggingHandler(os.Stdout, r)))
}
+3 -3
View File
@@ -17,15 +17,15 @@ limitations under the License.
package messagequeue package messagequeue
import ( import (
"log"
"os" "os"
"github.com/fission/fission/crd"
"github.com/fission/fission/mqtrigger/messageQueue" "github.com/fission/fission/mqtrigger/messageQueue"
"github.com/fission/fission/tpr"
"log"
) )
func Start(routerUrl string) error { func Start(routerUrl string) error {
fissionClient, _, err := tpr.MakeFissionClient() fissionClient, _, _, err := crd.MakeFissionClient()
if err != nil { if err != nil {
log.Fatalf("Failed to get fission client: %v", err) log.Fatalf("Failed to get fission client: %v", err)
} }
+13 -14
View File
@@ -21,10 +21,9 @@ import (
"time" "time"
log "github.com/sirupsen/logrus" 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/crd"
"github.com/fission/fission/tpr"
) )
const ( const (
@@ -48,7 +47,7 @@ type (
} }
MessageQueue interface { MessageQueue interface {
subscribe(trigger *tpr.Messagequeuetrigger) (messageQueueSubscription, error) subscribe(trigger *crd.MessageQueueTrigger) (messageQueueSubscription, error)
unsubscribe(triggerSub messageQueueSubscription) error unsubscribe(triggerSub messageQueueSubscription) error
} }
@@ -56,12 +55,12 @@ type (
reqChan chan request reqChan chan request
mqCfg MessageQueueConfig mqCfg MessageQueueConfig
triggers map[string]*triggerSubscription triggers map[string]*triggerSubscription
fissionClient *tpr.FissionClient fissionClient *crd.FissionClient
messageQueue MessageQueue messageQueue MessageQueue
} }
triggerSubscription struct { triggerSubscription struct {
trigger tpr.Messagequeuetrigger trigger crd.MessageQueueTrigger
subscription messageQueueSubscription subscription messageQueueSubscription
} }
@@ -76,7 +75,7 @@ type (
} }
) )
func MakeMessageQueueTriggerManager(fissionClient *tpr.FissionClient, routerUrl string, mqConfig MessageQueueConfig) *MessageQueueTriggerManager { func MakeMessageQueueTriggerManager(fissionClient *crd.FissionClient, routerUrl string, mqConfig MessageQueueConfig) *MessageQueueTriggerManager {
var messageQueue MessageQueue var messageQueue MessageQueue
var err error var err error
@@ -106,7 +105,7 @@ func (mqt *MessageQueueTriggerManager) service() {
switch req.requestType { switch req.requestType {
case ADD_TRIGGER: case ADD_TRIGGER:
var err error var err error
k := tpr.CacheKey(&req.triggerSub.trigger.Metadata) k := crd.CacheKey(&req.triggerSub.trigger.Metadata)
if _, ok := mqt.triggers[k]; ok { if _, ok := mqt.triggers[k]; ok {
err = errors.New("Trigger already exists") err = errors.New("Trigger already exists")
} else { } else {
@@ -120,7 +119,7 @@ func (mqt *MessageQueueTriggerManager) service() {
} }
req.respChan <- response{triggers: &copyTriggers} req.respChan <- response{triggers: &copyTriggers}
case DELETE_TRIGGER: case DELETE_TRIGGER:
delete(mqt.triggers, tpr.CacheKey(&req.triggerSub.trigger.Metadata)) delete(mqt.triggers, crd.CacheKey(&req.triggerSub.trigger.Metadata))
} }
} }
} }
@@ -146,11 +145,11 @@ func (mqt *MessageQueueTriggerManager) getAllTriggers() *map[string]*triggerSubs
return r.triggers return r.triggers
} }
func (mqt *MessageQueueTriggerManager) delTrigger(m *api.ObjectMeta) { func (mqt *MessageQueueTriggerManager) delTrigger(m *metav1.ObjectMeta) {
mqt.reqChan <- request{ mqt.reqChan <- request{
requestType: DELETE_TRIGGER, requestType: DELETE_TRIGGER,
triggerSub: &triggerSubscription{ triggerSub: &triggerSubscription{
trigger: tpr.Messagequeuetrigger{ trigger: crd.MessageQueueTrigger{
Metadata: *m, Metadata: *m,
}, },
}, },
@@ -160,14 +159,14 @@ func (mqt *MessageQueueTriggerManager) delTrigger(m *api.ObjectMeta) {
func (mqt *MessageQueueTriggerManager) syncTriggers() { func (mqt *MessageQueueTriggerManager) syncTriggers() {
for { for {
// get new set of triggers // get new set of triggers
newTriggers, err := mqt.fissionClient.Messagequeuetriggers(api.NamespaceAll).List(api.ListOptions{}) newTriggers, err := mqt.fissionClient.MessageQueueTriggers(metav1.NamespaceAll).List(metav1.ListOptions{})
if err != nil { if err != nil {
log.Fatalf("Failed to read message queue trigger list: %v", err) log.Fatalf("Failed to read message queue trigger list: %v", err)
} }
newTriggerMap := make(map[string]*tpr.Messagequeuetrigger) newTriggerMap := make(map[string]*crd.MessageQueueTrigger)
for index := range newTriggers.Items { for index := range newTriggers.Items {
newTrigger := &newTriggers.Items[index] newTrigger := &newTriggers.Items[index]
newTriggerMap[tpr.CacheKey(&newTrigger.Metadata)] = newTrigger newTriggerMap[crd.CacheKey(&newTrigger.Metadata)] = newTrigger
} }
// get current set of triggers // get current set of triggers
+4 -4
View File
@@ -29,7 +29,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/fission/fission" "github.com/fission/fission"
"github.com/fission/fission/tpr" "github.com/fission/fission/crd"
) )
const ( const (
@@ -58,7 +58,7 @@ func makeNatsMessageQueue(routerUrl string, mqCfg MessageQueueConfig) (MessageQu
return nats, nil return nats, nil
} }
func (nats Nats) subscribe(trigger *tpr.Messagequeuetrigger) (messageQueueSubscription, error) { func (nats Nats) subscribe(trigger *crd.MessageQueueTrigger) (messageQueueSubscription, error) {
subj := trigger.Spec.Topic subj := trigger.Spec.Topic
if !isTopicValidForNats(subj) { if !isTopicValidForNats(subj) {
@@ -88,10 +88,10 @@ func (nats Nats) unsubscribe(subscription messageQueueSubscription) error {
func isTopicValidForNats(topic string) bool { func isTopicValidForNats(topic string) bool {
// nats-streaming does not support wildcard channel. // nats-streaming does not support wildcard channel.
return nsUtil.IsSubjectValid(topic) return nsUtil.IsSubjectValid(topic, false)
} }
func msgHandler(nats *Nats, trigger *tpr.Messagequeuetrigger) func(*ns.Msg) { func msgHandler(nats *Nats, trigger *crd.MessageQueueTrigger) func(*ns.Msg) {
return func(msg *ns.Msg) { return func(msg *ns.Msg) {
// Support other function ref types // Support other function ref types

Some files were not shown because too many files have changed in this diff Show More