diff --git a/Documentation/Roadmap.md b/Documentation/Roadmap.md index 68907075..a6dd65cf 100644 --- a/Documentation/Roadmap.md +++ b/Documentation/Roadmap.md @@ -10,7 +10,7 @@ ## Fission API ([area-api](https://github.com/fission/fission/labels/area-api)) -- TPR-based controller +- CRD-based controller - API authentication - Aggregated API server diff --git a/Documentation/docs-site/content/_index.md b/Documentation/docs-site/content/_index.md index c411c061..a34e09d4 100644 --- a/Documentation/docs-site/content/_index.md +++ b/Documentation/docs-site/content/_index.md @@ -2,4 +2,6 @@ * [Installation guide](install) - * [Upgrade guide](upgrade-from-v0.1) \ No newline at end of file + * [Upgrade guide for v0.1 to v0.2](upgrade-from-v0.1) + + * [Upgrade guide for v0.3 to v0.4](upgrade-from-v0.3) \ No newline at end of file diff --git a/Documentation/docs-site/content/upgrade-from-v0.3.md b/Documentation/docs-site/content/upgrade-from-v0.3.md new file mode 100644 index 00000000..3e2dfd86 --- /dev/null +++ b/Documentation/docs-site/content/upgrade-from-v0.3.md @@ -0,0 +1,126 @@ +--- +title: "Upgrading from Fission v0.3 to v0.4.x" +date: 2017-11-04T03:38:29+08:00 +draft: false +--- + +## TL;DR + +ThirdPartyResource is replaced by CustomResource and will be entirely deprecated in Kubernetes 1.8. +Since Fission stores state in TPR, we need to migrate from TPRs to CRDs for future Kubernetes +release. + +Below we describe a tool for migrating your TPRs to CRDs. + +## How to Upgrade + +1. Get the v0.4-rc CLI +2. Get the Fission state from v0.3 install +3. Upgrade to Fission v0.4.0-rc +4. Upgrade Kubernetes cluster version to 1.7.x or higher +5. Remove all TPR definition (for Kubernetes 1.7.x) +6. Restore Fission state into CRDs + +### Get the new CLI + +#### OS X + +``` +$ curl -Lo fission https://github.com/fission/fission/releases/download/v0.4.0-rc/fission-cli-osx && chmod +x fission && sudo mv fission /usr/local/bin/ +``` + +#### Linux + +``` +$ curl -Lo fission https://github.com/fission/fission/releases/download/v0.4.0-rc/fission-cli-linux && chmod +x fission && sudo mv fission /usr/local/bin/ +``` + +#### Windows + +For Windows, you can use the linux binary on WSL. Or you can download +this windows executable: [fission.exe](https://github.com/fission/fission/releases/download/v0.4.0-rc/fission-cli-windows.exe) + +### Get Fission state from v0.3 install + +``` +fission --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 v0.4.0-rc + +Upgrade fission with a command similar to this: + +``` +helm upgrade fission-all --namespace fission +``` + +### Upgrade Kubernetes cluster version + +Since CustomResource is only supported on Kubernetes v1.7+ and higher, please make sure +that you upgrade to the right version that supports CustomResource. + +### Remove all TPR definition (for Kubernetes 1.7.x) + +** NOTICE **: This step will remove TPR definition from your kubernetes cluster. Please make sure that you dump all TPRs at the second step! + +Though Kubernetes will migrate TPRs to CRDs automatically when TPR definition is deleted if the same name CRD exists. We still need to make sure that there is no resource gets lost during the migration. Also, since we changed the capitalization of some CRDs to CamelCase (e.g. Httptrigger -> HTTPTrigger), we need to recreate those resources by ourselves. + +``` +fission tpr2crd delete +``` + +### Restore your Fission state into Fission v0.4.0-rc + +``` +fission tpr2crd restore --file state.json +``` + +This commands needs `$FISSION_URL` set to point to new fission installation. + +It uses the file created in the first step. It doesn't modify state.json. + +(Note that you can run this restore on any cluster; it doesn't have the be the same kubernetes +cluster as your old install.) + +### Verify + +Let's check the migration result, first run following command to check CRD established state. + +``` +kubectl get crd -o 'custom-columns=NAME:{.metadata.name},ESTABLISHED:{.status.conditions[?(@.type=="Established")].status}' +``` + +The output should be like this + +``` +NAME ESTABLISHED +environments.fission.io True +functions.fission.io True +httptriggers.fission.io True +kuberneteswatchtriggers.fission.io True +messagequeuetriggers.fission.io True +packages.fission.io True +timetriggers.fission.io True +``` + +And check that CRD resources you expect are there. + +``` +COMMAND: + fission [resource] list + +RESOURCES: + environments + functions + httptriggers + kuberneteswatchtriggers + messagequeuetriggers + packages + timetriggers +``` \ No newline at end of file diff --git a/buildermgr/api.go b/buildermgr/api.go index c5798634..f6417060 100644 --- a/buildermgr/api.go +++ b/buildermgr/api.go @@ -30,7 +30,7 @@ import ( "k8s.io/client-go/kubernetes" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) type ( @@ -39,14 +39,14 @@ type ( } BuilderMgr struct { - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient kubernetesClient *kubernetes.Clientset storageSvcUrl string namespace string } ) -func MakeBuilderMgr(fissionClient *tpr.FissionClient, +func MakeBuilderMgr(fissionClient *crd.FissionClient, kubernetesClient *kubernetes.Clientset, storageSvcUrl string, envBuilderNamespace string) *BuilderMgr { diff --git a/buildermgr/buildermgr.go b/buildermgr/buildermgr.go index 4ff64c2e..fb6ca8f2 100644 --- a/buildermgr/buildermgr.go +++ b/buildermgr/buildermgr.go @@ -19,12 +19,12 @@ package buildermgr import ( "log" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) // Start the buildermgr service. func Start(port int, storageSvcUrl string, envBuilderNamespace string) error { - fissionClient, kubernetesClient, err := tpr.MakeFissionClient() + fissionClient, kubernetesClient, _, err := crd.MakeFissionClient() if err != nil { log.Printf("Failed to get kubernetes client: %v", err) return err diff --git a/buildermgr/common.go b/buildermgr/common.go index a70904bf..0c4c2030 100644 --- a/buildermgr/common.go +++ b/buildermgr/common.go @@ -28,9 +28,9 @@ import ( "github.com/fission/fission" "github.com/fission/fission/builder" builderClient "github.com/fission/fission/builder/client" + "github.com/fission/fission/crd" "github.com/fission/fission/environments/fetcher" fetcherClient "github.com/fission/fission/environments/fetcher/client" - "github.com/fission/fission/tpr" ) // buildPackage helps to build source package into deployment package. @@ -43,13 +43,13 @@ import ( // 6. Update package status to succeed state // 7. Update package resource in package ref of functions that share the same package // *. Update package status to failed state,if any one of steps above failed -func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes.Clientset, +func buildPackage(fissionClient *crd.FissionClient, kubernetesClient *kubernetes.Clientset, builderNamespace string, storageSvcUrl string, buildReq BuildRequest) (buildLogs string, err error) { pkg, err := fissionClient.Packages( buildReq.Package.Namespace).Get(buildReq.Package.Name) if err != nil { - e := fmt.Sprintf("Error getting function TPR info: %v", err) + e := fmt.Sprintf("Error getting function CRD info: %v", err) log.Println(e) updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil) return e, fission.MakeError(500, e) @@ -64,7 +64,14 @@ func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes // update package status to running state, so that // 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 { e := fmt.Sprintf("Error setting package pending state: %v", err) log.Println(e) @@ -74,7 +81,7 @@ func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes env, err := fissionClient.Environments(metav1.NamespaceDefault).Get(pkg.Spec.Environment.Name) 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) updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil) return e, fission.MakeError(500, e) @@ -134,10 +141,11 @@ func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes log.Printf("Start updating info of package: %v", pkg.Metadata.Name) // update package status and also build logs - newPkgRV, err := updatePackage(fissionClient, pkg, + newPkgRV, err = updatePackage(fissionClient, pkg, fission.BuildStatusSucceeded, buildResp.BuildLogs, uploadResp) + pkg.Metadata.ResourceVersion = newPkgRV 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) updatePackage(fissionClient, pkg, fission.BuildStatusFailed, e, nil) return e, fission.MakeError(500, e) @@ -159,7 +167,7 @@ func buildPackage(fissionClient *tpr.FissionClient, kubernetesClient *kubernetes fn.Spec.Package.PackageRef.Namespace == pkg.Metadata.Namespace && fn.Spec.Package.PackageRef.ResourceVersion != pkg.Metadata.ResourceVersion { fn.Spec.Package.PackageRef.ResourceVersion = newPkgRV - // update TPR + // update CRD _, err = fissionClient.Functions(fn.Metadata.Namespace).Update(&fn) if err != nil { 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 } -func updatePackage(fissionClient *tpr.FissionClient, - pkg *tpr.Package, status fission.BuildStatus, buildLogs string, +func updatePackage(fissionClient *crd.FissionClient, + pkg *crd.Package, status fission.BuildStatus, buildLogs string, 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{ BuildStatus: status, BuildLog: buildLogs, diff --git a/buildermgr/envwatcher.go b/buildermgr/envwatcher.go index 6c84579d..4172a13a 100644 --- a/buildermgr/envwatcher.go +++ b/buildermgr/envwatcher.go @@ -30,7 +30,7 @@ import ( apiv1 "k8s.io/client-go/pkg/api/v1" "k8s.io/client-go/pkg/apis/extensions/v1beta1" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) type requestType int @@ -52,8 +52,8 @@ type ( envwRequest struct { requestType - env *tpr.Environment - envList []tpr.Environment + env *crd.Environment + envList []crd.Environment respChan chan envwResponse } @@ -66,14 +66,14 @@ type ( cache map[string]*builderInfo requestChan chan envwRequest builderNamespace string - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient kubernetesClient *kubernetes.Clientset fetcherImage string fetcherImagePullPolicy apiv1.PullPolicy } ) -func makeEnvironmentWatcher(fissionClient *tpr.FissionClient, +func makeEnvironmentWatcher(fissionClient *crd.FissionClient, kubernetesClient *kubernetes.Clientset, builderNamespace string) *environmentWatcher { fetcherImage := os.Getenv("FETCHER_IMAGE") @@ -144,7 +144,7 @@ func (envw *environmentWatcher) watchEnvironments() { time.Sleep(time.Second) break } - env := ev.Object.(*tpr.Environment) + env := ev.Object.(*crd.Environment) rv = env.Metadata.ResourceVersion envw.sync() } @@ -154,7 +154,7 @@ func (envw *environmentWatcher) watchEnvironments() { func (envw *environmentWatcher) sync() { envList, err := envw.fissionClient.Environments(metav1.NamespaceAll).List(metav1.ListOptions{}) 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 @@ -191,7 +191,7 @@ func (envw *environmentWatcher) service() { req.respChan <- envwResponse{builderInfo: builderInfo} case CLEANUP_BUILDERS: - latestEnvList := make(map[string]*tpr.Environment) + latestEnvList := make(map[string]*crd.Environment) for i := range req.envList { env := req.envList[i] 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, // the builder belongs to the environment will be out-of- // 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. 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) envw.requestChan <- envwRequest{ requestType: GET_BUILDER, @@ -252,14 +252,14 @@ func (envw *environmentWatcher) getEnvBuilder(env *tpr.Environment) (*builderInf return resp.builderInfo, resp.err } -func (envw *environmentWatcher) cleanupEnvBuilders(envs []tpr.Environment) { +func (envw *environmentWatcher) cleanupEnvBuilders(envs []crd.Environment) { envw.requestChan <- envwRequest{ requestType: CLEANUP_BUILDERS, envList: envs, } } -func (envw *environmentWatcher) createBuilder(env *tpr.Environment) (*builderInfo, error) { +func (envw *environmentWatcher) createBuilder(env *crd.Environment) (*builderInfo, error) { var svc *apiv1.Service var deploy *v1beta1.Deployment @@ -353,7 +353,7 @@ func (envw *environmentWatcher) getBuilderServiceList(sel map[string]string) ([] return svcList.Items, nil } -func (envw *environmentWatcher) createBuilderService(env *tpr.Environment) (*apiv1.Service, error) { +func (envw *environmentWatcher) createBuilderService(env *crd.Environment) (*apiv1.Service, error) { name := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion) sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion) service := apiv1.Service{ @@ -406,7 +406,7 @@ func (envw *environmentWatcher) getBuilderDeploymentList(sel map[string]string) 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" name := envw.getCacheKey(env.Metadata.Name, env.Metadata.ResourceVersion) sel := envw.getLabels(env.Metadata.Name, env.Metadata.ResourceVersion) diff --git a/buildermgr/pkgwatcher.go b/buildermgr/pkgwatcher.go index e2a5fbd5..c3f75101 100644 --- a/buildermgr/pkgwatcher.go +++ b/buildermgr/pkgwatcher.go @@ -25,19 +25,19 @@ import ( "k8s.io/client-go/kubernetes" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) type ( packageWatcher struct { - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient kubernetesClient *kubernetes.Clientset builderNamespace string storageSvcUrl string } ) -func makePackageWatcher(fissionClient *tpr.FissionClient, +func makePackageWatcher(fissionClient *crd.FissionClient, kubernetesClient *kubernetes.Clientset, builderNamespace string, storageSvcUrl string) *packageWatcher { pkgw := &packageWatcher{ fissionClient: fissionClient, @@ -66,7 +66,7 @@ func (pkgw *packageWatcher) watchPackages() { ResourceVersion: rv, }) if err != nil { - log.Fatalf("Error watching package TPR resources: %v", err) + log.Fatalf("Error watching package CRD resources: %v", err) } for { @@ -79,7 +79,7 @@ func (pkgw *packageWatcher) watchPackages() { time.Sleep(time.Second) break } - pkg := ev.Object.(*tpr.Package) + pkg := ev.Object.(*crd.Package) rv = pkg.Metadata.ResourceVersion // only do build for packages in pending state diff --git a/charts/fission-all/templates/deployment.yaml b/charts/fission-all/templates/deployment.yaml index b6e9d00f..2902b028 100644 --- a/charts/fission-all/templates/deployment.yaml +++ b/charts/fission-all/templates/deployment.yaml @@ -131,7 +131,7 @@ roleRef: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: - name: fission-tpr + name: fission-crd subjects: - kind: ServiceAccount name: fission-svc @@ -152,7 +152,7 @@ metadata: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: - name: fission-fetcher-tpr + name: fission-fetcher-crd subjects: - kind: ServiceAccount name: fission-fetcher @@ -173,7 +173,7 @@ metadata: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: - name: fission-builder-tpr + name: fission-builder-crd subjects: - kind: ServiceAccount name: fission-builder diff --git a/charts/fission-core/templates/deployment.yaml b/charts/fission-core/templates/deployment.yaml index 635c965d..0ffc3aef 100644 --- a/charts/fission-core/templates/deployment.yaml +++ b/charts/fission-core/templates/deployment.yaml @@ -131,7 +131,7 @@ roleRef: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: - name: fission-tpr + name: fission-crd subjects: - kind: ServiceAccount name: fission-svc @@ -152,7 +152,7 @@ metadata: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: - name: fission-fetcher-tpr + name: fission-fetcher-crd subjects: - kind: ServiceAccount name: fission-fetcher @@ -173,7 +173,7 @@ metadata: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: - name: fission-builder-tpr + name: fission-builder-crd subjects: - kind: ServiceAccount name: fission-builder diff --git a/controller/api.go b/controller/api.go index 2a263bee..1b1afc37 100644 --- a/controller/api.go +++ b/controller/api.go @@ -30,13 +30,13 @@ import ( "k8s.io/client-go/kubernetes" "github.com/fission/fission" + "github.com/fission/fission/crd" "github.com/fission/fission/fission/logdb" - "github.com/fission/fission/tpr" ) type ( API struct { - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient kubernetesClient *kubernetes.Clientset storageServiceUrl string builderManagerUrl string @@ -51,7 +51,7 @@ type ( ) func MakeAPI() (*API, error) { - api, err := makeTPRBackedAPI() + api, err := makeCRDBackedAPI() u := os.Getenv("STORAGE_SERVICE_URL") if len(u) > 0 { @@ -176,6 +176,8 @@ func (api *API) Serve(port int) { r.HandleFunc("/v2/triggers/messagequeue/{mqTrigger}", api.MessageQueueTriggerApiUpdate).Methods("PUT") r.HandleFunc("/v2/triggers/messagequeue/{mqTrigger}", api.MessageQueueTriggerApiDelete).Methods("DELETE") + r.HandleFunc("/v2/deleteTpr", api.Tpr2crdApi).Methods("DELETE") + r.HandleFunc("/proxy/{dbType}", api.FunctionLogsApiPost).Methods("POST") r.HandleFunc("/proxy/storage/v1/archive", api.StorageServiceProxy) r.HandleFunc("/proxy/buildermgr/v1/build", api.BuilderManagerBuildProxy) diff --git a/controller/api_test.go b/controller/api_test.go index 2658c229..f36f2b23 100644 --- a/controller/api_test.go +++ b/controller/api_test.go @@ -18,6 +18,7 @@ package controller import ( "flag" + "fmt" "io/ioutil" "log" "net/http" @@ -29,7 +30,7 @@ import ( "github.com/fission/fission" "github.com/fission/fission/controller/client" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) var g struct { @@ -72,12 +73,9 @@ func assertCronSpecFails(err error) { } func TestFunctionApi(t *testing.T) { - name1 := "foo" - name2 := "bar" - - testFunc := &tpr.Function{ + testFunc := &crd.Function{ Metadata: metav1.ObjectMeta{ - Name: name1, + Name: "foo", Namespace: metav1.NamespaceDefault, }, Spec: fission.FunctionSpec{ @@ -95,24 +93,30 @@ func TestFunctionApi(t *testing.T) { }) assertNotFoundFailure(err, "function") - _, err = g.client.FunctionCreate(testFunc) + m, err := g.client.FunctionCreate(testFunc) panicIf(err) + defer func() { + err := g.client.FunctionDelete(m) + panicIf(err) + }() _, err = g.client.FunctionCreate(testFunc) assertNameReuseFailure(err, "function") + testFunc.Metadata.ResourceVersion = m.ResourceVersion testFunc.Spec.Package.FunctionName = "yyy" _, err = g.client.FunctionUpdate(testFunc) panicIf(err) - testFunc.Metadata.Name = name2 - _, err = g.client.FunctionCreate(testFunc) + testFunc.Metadata.ResourceVersion = "" + testFunc.Metadata.Name = "bar" + m2, err := g.client.FunctionCreate(testFunc) panicIf(err) + defer g.client.FunctionDelete(m2) funcs, err := g.client.FunctionList() panicIf(err) - assert(len(funcs) == 2, - "created two functions, but didn't find them") + assert(len(funcs) == 2, fmt.Sprintf("created two functions, but found %v", len(funcs))) funcs_url := g.client.Url + "/v2/functions" resp, err := http.Get(funcs_url) @@ -127,15 +131,10 @@ func TestFunctionApi(t *testing.T) { } } assert(found, "incorrect response content type") - - err = g.client.FunctionDelete(&metav1.ObjectMeta{Name: name1, Namespace: metav1.NamespaceDefault}) - panicIf(err) - err = g.client.FunctionDelete(&metav1.ObjectMeta{Name: name2, Namespace: metav1.NamespaceDefault}) - panicIf(err) } func TestHTTPTriggerApi(t *testing.T) { - testTrigger := &tpr.Httptrigger{ + testTrigger := &crd.HTTPTrigger{ Metadata: metav1.ObjectMeta{ Name: "foo", Namespace: metav1.NamespaceDefault, @@ -165,10 +164,12 @@ func TestHTTPTriggerApi(t *testing.T) { panicIf(err) assert(testTrigger.Spec == tr.Spec, "trigger should match after reading") + testTrigger.Metadata.ResourceVersion = m.ResourceVersion testTrigger.Spec.RelativeURL = "/hi" _, err = g.client.HTTPTriggerUpdate(testTrigger) panicIf(err) + testTrigger.Metadata.ResourceVersion = "" testTrigger.Metadata.Name = "yyy" _, err = g.client.HTTPTriggerCreate(testTrigger) assert(err != nil, "duplicate trigger should not be allowed") @@ -180,11 +181,11 @@ func TestHTTPTriggerApi(t *testing.T) { ts, err := g.client.HTTPTriggerList() panicIf(err) - assert(len(ts) == 2, "created two triggers, but didn't find them") + assert(len(ts) == 2, fmt.Sprintf("created two triggers, but found %v", len(ts))) } func TestEnvironmentApi(t *testing.T) { - testEnv := &tpr.Environment{ + testEnv := &crd.Environment{ Metadata: metav1.ObjectMeta{ Name: "foo", Namespace: metav1.NamespaceDefault, @@ -212,10 +213,12 @@ func TestEnvironmentApi(t *testing.T) { panicIf(err) assert(testEnv.Spec == e.Spec, "env should match after reading") + testEnv.Metadata.ResourceVersion = m.ResourceVersion testEnv.Spec.Runtime.Image = "another-img" _, err = g.client.EnvironmentUpdate(testEnv) panicIf(err) + testEnv.Metadata.ResourceVersion = "" testEnv.Metadata.Name = "bar" m2, err := g.client.EnvironmentCreate(testEnv) panicIf(err) @@ -223,11 +226,11 @@ func TestEnvironmentApi(t *testing.T) { ts, err := g.client.EnvironmentList() panicIf(err) - assert(len(ts) == 2, "created two envs, but didn't find them") + assert(len(ts) == 2, fmt.Sprintf("created two envs, but found %v", len(ts))) } func TestWatchApi(t *testing.T) { - testWatch := &tpr.Kuberneteswatchtrigger{ + testWatch := &crd.KubernetesWatchTrigger{ Metadata: metav1.ObjectMeta{ Name: "xxx", Namespace: metav1.NamespaceDefault, @@ -267,11 +270,11 @@ func TestWatchApi(t *testing.T) { ws, err := g.client.WatchList() panicIf(err) - assert(len(ws) == 2, "created two envs, but didn't find them") + assert(len(ws) == 2, fmt.Sprintf("created two watches, but found %v", len(ws))) } func TestTimeTriggerApi(t *testing.T) { - testTrigger := &tpr.Timetrigger{ + testTrigger := &crd.TimeTrigger{ Metadata: metav1.ObjectMeta{ Name: "xxx", Namespace: metav1.NamespaceDefault, @@ -298,10 +301,12 @@ func TestTimeTriggerApi(t *testing.T) { panicIf(err) assert(testTrigger.Spec == tr.Spec, "trigger should match after reading") + testTrigger.Metadata.ResourceVersion = m.ResourceVersion testTrigger.Spec.Cron = "@hourly" _, err = g.client.TimeTriggerUpdate(testTrigger) panicIf(err) + testTrigger.Metadata.ResourceVersion = "" testTrigger.Metadata.Name = "yyy" testTrigger.Spec.Cron = "Not valid cron spec" _, err = g.client.TimeTriggerCreate(testTrigger) @@ -309,7 +314,7 @@ func TestTimeTriggerApi(t *testing.T) { ts, err := g.client.TimeTriggerList() panicIf(err) - assert(len(ts) == 1, "created one trigger, but didn't find it") + assert(len(ts) == 1, fmt.Sprintf("created two time triggers, but found %v", len(ts))) } func TestMain(m *testing.M) { @@ -324,7 +329,7 @@ func TestMain(m *testing.M) { go Start(8888) - time.Sleep(time.Second) + time.Sleep(5 * time.Second) g.client = client.MakeClient("http://localhost:8888") resp, err := http.Get("http://localhost:8888/") diff --git a/controller/client/environment.go b/controller/client/environment.go index 03faa838..d7cc8f0c 100644 --- a/controller/client/environment.go +++ b/controller/client/environment.go @@ -24,10 +24,10 @@ import ( 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) (*metav1.ObjectMeta, error) { +func (c *Client) EnvironmentCreate(env *crd.Environment) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(env) if err != nil { return nil, err @@ -53,7 +53,7 @@ func (c *Client) EnvironmentCreate(env *tpr.Environment) (*metav1.ObjectMeta, er return &m, nil } -func (c *Client) EnvironmentGet(m *metav1.ObjectMeta) (*tpr.Environment, error) { +func (c *Client) EnvironmentGet(m *metav1.ObjectMeta) (*crd.Environment, error) { relativeUrl := fmt.Sprintf("environments/%v", m.Name) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) @@ -68,7 +68,7 @@ func (c *Client) EnvironmentGet(m *metav1.ObjectMeta) (*tpr.Environment, error) return nil, err } - var env tpr.Environment + var env crd.Environment err = json.Unmarshal(body, &env) if err != nil { return nil, err @@ -77,7 +77,7 @@ func (c *Client) EnvironmentGet(m *metav1.ObjectMeta) (*tpr.Environment, error) return &env, nil } -func (c *Client) EnvironmentUpdate(env *tpr.Environment) (*metav1.ObjectMeta, error) { +func (c *Client) EnvironmentUpdate(env *crd.Environment) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(env) if err != nil { return nil, err @@ -110,7 +110,7 @@ func (c *Client) EnvironmentDelete(m *metav1.ObjectMeta) error { return c.delete(relativeUrl) } -func (c *Client) EnvironmentList() ([]tpr.Environment, error) { +func (c *Client) EnvironmentList() ([]crd.Environment, error) { resp, err := http.Get(c.url("environments")) if err != nil { return nil, err @@ -122,7 +122,7 @@ func (c *Client) EnvironmentList() ([]tpr.Environment, error) { return nil, err } - envs := make([]tpr.Environment, 0) + envs := make([]crd.Environment, 0) err = json.Unmarshal(body, &envs) if err != nil { return nil, err diff --git a/controller/client/function.go b/controller/client/function.go index bebf8fd3..51c68e0d 100644 --- a/controller/client/function.go +++ b/controller/client/function.go @@ -24,10 +24,10 @@ import ( 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) (*metav1.ObjectMeta, error) { +func (c *Client) FunctionCreate(f *crd.Function) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(f) if err != nil { @@ -54,7 +54,7 @@ func (c *Client) FunctionCreate(f *tpr.Function) (*metav1.ObjectMeta, error) { return &m, nil } -func (c *Client) FunctionGet(m *metav1.ObjectMeta) (*tpr.Function, error) { +func (c *Client) FunctionGet(m *metav1.ObjectMeta) (*crd.Function, error) { relativeUrl := fmt.Sprintf("functions/%v", m.Name) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) @@ -69,7 +69,7 @@ func (c *Client) FunctionGet(m *metav1.ObjectMeta) (*tpr.Function, error) { return nil, err } - var f tpr.Function + var f crd.Function err = json.Unmarshal(body, &f) if err != nil { return nil, err @@ -92,7 +92,7 @@ func (c *Client) FunctionGetRawDeployment(m *metav1.ObjectMeta) ([]byte, error) return c.handleResponse(resp) } -func (c *Client) FunctionUpdate(f *tpr.Function) (*metav1.ObjectMeta, error) { +func (c *Client) FunctionUpdate(f *crd.Function) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(f) if err != nil { return nil, err @@ -124,7 +124,7 @@ func (c *Client) FunctionDelete(m *metav1.ObjectMeta) error { return c.delete(relativeUrl) } -func (c *Client) FunctionList() ([]tpr.Function, error) { +func (c *Client) FunctionList() ([]crd.Function, error) { resp, err := http.Get(c.url("functions")) if err != nil { return nil, err @@ -136,7 +136,7 @@ func (c *Client) FunctionList() ([]tpr.Function, error) { return nil, err } - funcs := make([]tpr.Function, 0) + funcs := make([]crd.Function, 0) err = json.Unmarshal(body, &funcs) if err != nil { return nil, err diff --git a/controller/client/httptrigger.go b/controller/client/httptrigger.go index 789fa9e2..cd7cf15c 100644 --- a/controller/client/httptrigger.go +++ b/controller/client/httptrigger.go @@ -24,10 +24,10 @@ import ( 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) (*metav1.ObjectMeta, error) { +func (c *Client) HTTPTriggerCreate(t *crd.HTTPTrigger) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(t) if err != nil { return nil, err @@ -53,7 +53,7 @@ func (c *Client) HTTPTriggerCreate(t *tpr.Httptrigger) (*metav1.ObjectMeta, erro return &m, nil } -func (c *Client) HTTPTriggerGet(m *metav1.ObjectMeta) (*tpr.Httptrigger, error) { +func (c *Client) HTTPTriggerGet(m *metav1.ObjectMeta) (*crd.HTTPTrigger, error) { relativeUrl := fmt.Sprintf("triggers/http/%v", m.Name) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) @@ -68,7 +68,7 @@ func (c *Client) HTTPTriggerGet(m *metav1.ObjectMeta) (*tpr.Httptrigger, error) return nil, err } - var t tpr.Httptrigger + var t crd.HTTPTrigger err = json.Unmarshal(body, &t) if err != nil { return nil, err @@ -77,7 +77,7 @@ func (c *Client) HTTPTriggerGet(m *metav1.ObjectMeta) (*tpr.Httptrigger, error) return &t, nil } -func (c *Client) HTTPTriggerUpdate(t *tpr.Httptrigger) (*metav1.ObjectMeta, error) { +func (c *Client) HTTPTriggerUpdate(t *crd.HTTPTrigger) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(t) if err != nil { return nil, err @@ -109,7 +109,7 @@ func (c *Client) HTTPTriggerDelete(m *metav1.ObjectMeta) error { return c.delete(relativeUrl) } -func (c *Client) HTTPTriggerList() ([]tpr.Httptrigger, error) { +func (c *Client) HTTPTriggerList() ([]crd.HTTPTrigger, error) { resp, err := http.Get(c.url("triggers/http")) if err != nil { return nil, err @@ -121,7 +121,7 @@ func (c *Client) HTTPTriggerList() ([]tpr.Httptrigger, error) { return nil, err } - triggers := make([]tpr.Httptrigger, 0) + triggers := make([]crd.HTTPTrigger, 0) err = json.Unmarshal(body, &triggers) if err != nil { return nil, err diff --git a/controller/client/kuberneteswatchtrigger.go b/controller/client/kuberneteswatchtrigger.go index fb5594a1..d6f97e70 100644 --- a/controller/client/kuberneteswatchtrigger.go +++ b/controller/client/kuberneteswatchtrigger.go @@ -25,10 +25,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) -func (c *Client) WatchCreate(w *tpr.Kuberneteswatchtrigger) (*metav1.ObjectMeta, error) { +func (c *Client) WatchCreate(w *crd.KubernetesWatchTrigger) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(w) if err != nil { return nil, err @@ -54,7 +54,7 @@ func (c *Client) WatchCreate(w *tpr.Kuberneteswatchtrigger) (*metav1.ObjectMeta, return &m, nil } -func (c *Client) WatchGet(m *metav1.ObjectMeta) (*tpr.Kuberneteswatchtrigger, error) { +func (c *Client) WatchGet(m *metav1.ObjectMeta) (*crd.KubernetesWatchTrigger, error) { relativeUrl := fmt.Sprintf("watches/%v", m.Name) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) @@ -69,7 +69,7 @@ func (c *Client) WatchGet(m *metav1.ObjectMeta) (*tpr.Kuberneteswatchtrigger, er return nil, err } - var w tpr.Kuberneteswatchtrigger + var w crd.KubernetesWatchTrigger err = json.Unmarshal(body, &w) if err != nil { return nil, err @@ -78,7 +78,7 @@ func (c *Client) WatchGet(m *metav1.ObjectMeta) (*tpr.Kuberneteswatchtrigger, er return &w, nil } -func (c *Client) WatchUpdate(w *tpr.Kuberneteswatchtrigger) (*metav1.ObjectMeta, error) { +func (c *Client) WatchUpdate(w *crd.KubernetesWatchTrigger) (*metav1.ObjectMeta, error) { return nil, fission.MakeError(fission.ErrorNotImplmented, "watch update not implemented") } @@ -89,7 +89,7 @@ func (c *Client) WatchDelete(m *metav1.ObjectMeta) error { return c.delete(relativeUrl) } -func (c *Client) WatchList() ([]tpr.Kuberneteswatchtrigger, error) { +func (c *Client) WatchList() ([]crd.KubernetesWatchTrigger, error) { resp, err := http.Get(c.url("watches")) if err != nil { return nil, err @@ -101,7 +101,7 @@ func (c *Client) WatchList() ([]tpr.Kuberneteswatchtrigger, error) { return nil, err } - watches := make([]tpr.Kuberneteswatchtrigger, 0) + watches := make([]crd.KubernetesWatchTrigger, 0) err = json.Unmarshal(body, &watches) if err != nil { return nil, err diff --git a/controller/client/mqtrigger.go b/controller/client/mqtrigger.go index cba162b2..2f937e25 100644 --- a/controller/client/mqtrigger.go +++ b/controller/client/mqtrigger.go @@ -24,10 +24,10 @@ import ( 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) (*metav1.ObjectMeta, error) { +func (c *Client) MessageQueueTriggerCreate(t *crd.MessageQueueTrigger) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(t) if err != nil { return nil, err @@ -53,7 +53,7 @@ func (c *Client) MessageQueueTriggerCreate(t *tpr.Messagequeuetrigger) (*metav1. return &m, nil } -func (c *Client) MessageQueueTriggerGet(m *metav1.ObjectMeta) (*tpr.Messagequeuetrigger, error) { +func (c *Client) MessageQueueTriggerGet(m *metav1.ObjectMeta) (*crd.MessageQueueTrigger, error) { relativeUrl := fmt.Sprintf("triggers/messagequeue/%v", m.Name) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) @@ -68,7 +68,7 @@ func (c *Client) MessageQueueTriggerGet(m *metav1.ObjectMeta) (*tpr.Messagequeue return nil, err } - var t tpr.Messagequeuetrigger + var t crd.MessageQueueTrigger err = json.Unmarshal(body, &t) if err != nil { return nil, err @@ -77,7 +77,7 @@ func (c *Client) MessageQueueTriggerGet(m *metav1.ObjectMeta) (*tpr.Messagequeue return &t, nil } -func (c *Client) MessageQueueTriggerUpdate(mqTrigger *tpr.Messagequeuetrigger) (*metav1.ObjectMeta, error) { +func (c *Client) MessageQueueTriggerUpdate(mqTrigger *crd.MessageQueueTrigger) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(mqTrigger) if err != nil { return nil, err @@ -109,7 +109,7 @@ func (c *Client) MessageQueueTriggerDelete(m *metav1.ObjectMeta) error { return c.delete(relativeUrl) } -func (c *Client) MessageQueueTriggerList(mqType string) ([]tpr.Messagequeuetrigger, error) { +func (c *Client) MessageQueueTriggerList(mqType string) ([]crd.MessageQueueTrigger, error) { relativeUrl := "triggers/messagequeue" if len(mqType) > 0 { // TODO remove this, replace with field selector @@ -127,7 +127,7 @@ func (c *Client) MessageQueueTriggerList(mqType string) ([]tpr.Messagequeuetrigg return nil, err } - triggers := make([]tpr.Messagequeuetrigger, 0) + triggers := make([]crd.MessageQueueTrigger, 0) err = json.Unmarshal(body, &triggers) if err != nil { return nil, err diff --git a/controller/client/package.go b/controller/client/package.go index ab43fbcd..87159aef 100644 --- a/controller/client/package.go +++ b/controller/client/package.go @@ -24,10 +24,10 @@ import ( 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) (*metav1.ObjectMeta, error) { +func (c *Client) PackageCreate(f *crd.Package) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(f) if err != nil { @@ -54,7 +54,7 @@ func (c *Client) PackageCreate(f *tpr.Package) (*metav1.ObjectMeta, error) { return &m, nil } -func (c *Client) PackageGet(m *metav1.ObjectMeta) (*tpr.Package, error) { +func (c *Client) PackageGet(m *metav1.ObjectMeta) (*crd.Package, error) { relativeUrl := fmt.Sprintf("packages/%v", m.Name) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) @@ -69,7 +69,7 @@ func (c *Client) PackageGet(m *metav1.ObjectMeta) (*tpr.Package, error) { return nil, err } - var f tpr.Package + var f crd.Package err = json.Unmarshal(body, &f) if err != nil { return nil, err @@ -78,7 +78,7 @@ func (c *Client) PackageGet(m *metav1.ObjectMeta) (*tpr.Package, error) { return &f, nil } -func (c *Client) PackageUpdate(f *tpr.Package) (*metav1.ObjectMeta, error) { +func (c *Client) PackageUpdate(f *crd.Package) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(f) if err != nil { return nil, err @@ -110,7 +110,7 @@ func (c *Client) PackageDelete(m *metav1.ObjectMeta) error { return c.delete(relativeUrl) } -func (c *Client) PackageList() ([]tpr.Package, error) { +func (c *Client) PackageList() ([]crd.Package, error) { resp, err := http.Get(c.url("packages")) if err != nil { return nil, err @@ -122,7 +122,7 @@ func (c *Client) PackageList() ([]tpr.Package, error) { return nil, err } - funcs := make([]tpr.Package, 0) + funcs := make([]crd.Package, 0) err = json.Unmarshal(body, &funcs) if err != nil { return nil, err diff --git a/controller/client/timetrigger.go b/controller/client/timetrigger.go index 37a721a0..971d7df7 100644 --- a/controller/client/timetrigger.go +++ b/controller/client/timetrigger.go @@ -24,10 +24,10 @@ import ( 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) (*metav1.ObjectMeta, error) { +func (c *Client) TimeTriggerCreate(t *crd.TimeTrigger) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(t) if err != nil { return nil, err @@ -53,7 +53,7 @@ func (c *Client) TimeTriggerCreate(t *tpr.Timetrigger) (*metav1.ObjectMeta, erro return &m, nil } -func (c *Client) TimeTriggerGet(m *metav1.ObjectMeta) (*tpr.Timetrigger, error) { +func (c *Client) TimeTriggerGet(m *metav1.ObjectMeta) (*crd.TimeTrigger, error) { relativeUrl := fmt.Sprintf("triggers/time/%v", m.Name) relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace) @@ -68,7 +68,7 @@ func (c *Client) TimeTriggerGet(m *metav1.ObjectMeta) (*tpr.Timetrigger, error) return nil, err } - var t tpr.Timetrigger + var t crd.TimeTrigger err = json.Unmarshal(body, &t) if err != nil { return nil, err @@ -77,7 +77,7 @@ func (c *Client) TimeTriggerGet(m *metav1.ObjectMeta) (*tpr.Timetrigger, error) return &t, nil } -func (c *Client) TimeTriggerUpdate(t *tpr.Timetrigger) (*metav1.ObjectMeta, error) { +func (c *Client) TimeTriggerUpdate(t *crd.TimeTrigger) (*metav1.ObjectMeta, error) { reqbody, err := json.Marshal(t) if err != nil { return nil, err @@ -109,7 +109,7 @@ func (c *Client) TimeTriggerDelete(m *metav1.ObjectMeta) error { return c.delete(relativeUrl) } -func (c *Client) TimeTriggerList() ([]tpr.Timetrigger, error) { +func (c *Client) TimeTriggerList() ([]crd.TimeTrigger, error) { resp, err := http.Get(c.url("triggers/time")) if err != nil { return nil, err @@ -121,7 +121,7 @@ func (c *Client) TimeTriggerList() ([]tpr.Timetrigger, error) { return nil, err } - triggers := make([]tpr.Timetrigger, 0) + triggers := make([]crd.TimeTrigger, 0) err = json.Unmarshal(body, &triggers) if err != nil { return nil, err diff --git a/controller/controller.go b/controller/controller.go index f6027d20..d7cabd70 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -19,21 +19,21 @@ package controller import ( "log" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func Start(port int) { - fc, kc, err := tpr.MakeFissionClient() + fc, _, apiExtClient, err := crd.MakeFissionClient() if err != nil { log.Fatalf("Failed to connect to K8s API: %v", err) } - err = tpr.EnsureFissionTPRs(kc) + err = crd.EnsureFissionCRDs(apiExtClient) if err != nil { - log.Fatalf("Failed to create fission TPRs: %v", err) + log.Fatalf("Failed to create fission CRDs: %v", err) } - fc.WaitForTPRs() + fc.WaitForCRDs() api, err := MakeAPI() if err != nil { diff --git a/controller/tpr.go b/controller/crd.go similarity index 88% rename from controller/tpr.go rename to controller/crd.go index 82a6f6c8..c8e20da3 100644 --- a/controller/tpr.go +++ b/controller/crd.go @@ -20,11 +20,11 @@ import ( "errors" "regexp" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) -func makeTPRBackedAPI() (*API, error) { - fissionClient, kubernetesClient, err := tpr.MakeFissionClient() +func makeCRDBackedAPI() (*API, error) { + fissionClient, kubernetesClient, _, err := crd.MakeFissionClient() if err != nil { return nil, err } diff --git a/controller/environmentApi.go b/controller/environmentApi.go index 7af0a129..9c32e442 100644 --- a/controller/environmentApi.go +++ b/controller/environmentApi.go @@ -26,7 +26,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func (a *API) EnvironmentApiList(w http.ResponseWriter, r *http.Request) { @@ -52,7 +52,7 @@ func (a *API) EnvironmentApiCreate(w http.ResponseWriter, r *http.Request) { return } - var env tpr.Environment + var env crd.Environment err = json.Unmarshal(body, &env) if err != nil { log.Printf("Failed to unmarshal request body: [%v]", body) @@ -115,7 +115,7 @@ func (a *API) EnvironmentApiUpdate(w http.ResponseWriter, r *http.Request) { return } - var env tpr.Environment + var env crd.Environment err = json.Unmarshal(body, &env) if err != nil { a.respondWithError(w, err) diff --git a/controller/functionApi.go b/controller/functionApi.go index e6283626..e6b77b03 100644 --- a/controller/functionApi.go +++ b/controller/functionApi.go @@ -34,7 +34,7 @@ import ( restclient "k8s.io/client-go/rest" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func (a *API) FunctionApiList(w http.ResponseWriter, r *http.Request) { @@ -60,7 +60,7 @@ func (a *API) FunctionApiCreate(w http.ResponseWriter, r *http.Request) { return } - var f tpr.Function + var f crd.Function err = json.Unmarshal(body, &f) if err != nil { a.respondWithError(w, err) @@ -121,7 +121,7 @@ func (a *API) FunctionApiUpdate(w http.ResponseWriter, r *http.Request) { return } - var f tpr.Function + var f crd.Function err = json.Unmarshal(body, &f) if err != nil { a.respondWithError(w, err) diff --git a/controller/httpTriggerApi.go b/controller/httpTriggerApi.go index 58fc5972..a6b1c3b3 100644 --- a/controller/httpTriggerApi.go +++ b/controller/httpTriggerApi.go @@ -26,11 +26,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func (a *API) HTTPTriggerApiList(w http.ResponseWriter, r *http.Request) { - triggers, err := a.fissionClient.Httptriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) + triggers, err := a.fissionClient.HTTPTriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) if err != nil { a.respondWithError(w, err) return @@ -45,8 +45,8 @@ func (a *API) HTTPTriggerApiList(w http.ResponseWriter, r *http.Request) { a.respondWithSuccess(w, resp) } -func (a *API) checkHttpTriggerDuplicates(t *tpr.Httptrigger) error { - triggers, err := a.fissionClient.Httptriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) +func (a *API) checkHTTPTriggerDuplicates(t *crd.HTTPTrigger) error { + triggers, err := a.fissionClient.HTTPTriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) if err != nil { return err } @@ -67,7 +67,7 @@ func (a *API) HTTPTriggerApiCreate(w http.ResponseWriter, r *http.Request) { return } - var t tpr.Httptrigger + var t crd.HTTPTrigger err = json.Unmarshal(body, &t) if err != nil { a.respondWithError(w, err) @@ -81,13 +81,13 @@ func (a *API) HTTPTriggerApiCreate(w http.ResponseWriter, r *http.Request) { } // Ensure we don't have a duplicate HTTP route defined (same URL and method) - err = a.checkHttpTriggerDuplicates(&t) + err = a.checkHTTPTriggerDuplicates(&t) if err != nil { a.respondWithError(w, err) return } - tnew, err := a.fissionClient.Httptriggers(t.Metadata.Namespace).Create(&t) + tnew, err := a.fissionClient.HTTPTriggers(t.Metadata.Namespace).Create(&t) if err != nil { a.respondWithError(w, err) return @@ -111,7 +111,7 @@ func (a *API) HTTPTriggerApiGet(w http.ResponseWriter, r *http.Request) { ns = metav1.NamespaceDefault } - t, err := a.fissionClient.Httptriggers(ns).Get(name) + t, err := a.fissionClient.HTTPTriggers(ns).Get(name) if err != nil { a.respondWithError(w, err) return @@ -136,7 +136,7 @@ func (a *API) HTTPTriggerApiUpdate(w http.ResponseWriter, r *http.Request) { return } - var t tpr.Httptrigger + var t crd.HTTPTrigger err = json.Unmarshal(body, &t) if err != nil { a.respondWithError(w, err) @@ -149,13 +149,13 @@ func (a *API) HTTPTriggerApiUpdate(w http.ResponseWriter, r *http.Request) { return } - err = a.checkHttpTriggerDuplicates(&t) + err = a.checkHTTPTriggerDuplicates(&t) if err != nil { a.respondWithError(w, err) return } - tnew, err := a.fissionClient.Httptriggers(t.Metadata.Namespace).Update(&t) + tnew, err := a.fissionClient.HTTPTriggers(t.Metadata.Namespace).Update(&t) if err != nil { a.respondWithError(w, err) return @@ -177,7 +177,7 @@ func (a *API) HTTPTriggerApiDelete(w http.ResponseWriter, r *http.Request) { ns = metav1.NamespaceDefault } - err := a.fissionClient.Httptriggers(ns).Delete(name, &metav1.DeleteOptions{}) + err := a.fissionClient.HTTPTriggers(ns).Delete(name, &metav1.DeleteOptions{}) if err != nil { a.respondWithError(w, err) return diff --git a/controller/mqTriggerApi.go b/controller/mqTriggerApi.go index eaedd764..9ecefb67 100644 --- a/controller/mqTriggerApi.go +++ b/controller/mqTriggerApi.go @@ -25,12 +25,12 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func (a *API) MessageQueueTriggerApiList(w http.ResponseWriter, r *http.Request) { //mqType := r.FormValue("mqtype") // ignored for now - triggers, err := a.fissionClient.Messagequeuetriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) + triggers, err := a.fissionClient.MessageQueueTriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) if err != nil { a.respondWithError(w, err) return @@ -50,7 +50,7 @@ func (a *API) MessageQueueTriggerApiCreate(w http.ResponseWriter, r *http.Reques return } - var mqTrigger tpr.Messagequeuetrigger + var mqTrigger crd.MessageQueueTrigger err = json.Unmarshal(body, &mqTrigger) if err != nil { a.respondWithError(w, err) @@ -63,7 +63,7 @@ func (a *API) MessageQueueTriggerApiCreate(w http.ResponseWriter, r *http.Reques return } - tnew, err := a.fissionClient.Messagequeuetriggers(mqTrigger.Metadata.Namespace).Create(&mqTrigger) + tnew, err := a.fissionClient.MessageQueueTriggers(mqTrigger.Metadata.Namespace).Create(&mqTrigger) if err != nil { a.respondWithError(w, err) return @@ -86,7 +86,7 @@ func (a *API) MessageQueueTriggerApiGet(w http.ResponseWriter, r *http.Request) ns = metav1.NamespaceDefault } - mqTrigger, err := a.fissionClient.Messagequeuetriggers(ns).Get(name) + mqTrigger, err := a.fissionClient.MessageQueueTriggers(ns).Get(name) if err != nil { a.respondWithError(w, err) return @@ -109,7 +109,7 @@ func (a *API) MessageQueueTriggerApiUpdate(w http.ResponseWriter, r *http.Reques return } - var mqTrigger tpr.Messagequeuetrigger + var mqTrigger crd.MessageQueueTrigger err = json.Unmarshal(body, &mqTrigger) if err != nil { a.respondWithError(w, err) @@ -122,7 +122,7 @@ func (a *API) MessageQueueTriggerApiUpdate(w http.ResponseWriter, r *http.Reques return } - tnew, err := a.fissionClient.Messagequeuetriggers(mqTrigger.Metadata.Namespace).Update(&mqTrigger) + tnew, err := a.fissionClient.MessageQueueTriggers(mqTrigger.Metadata.Namespace).Update(&mqTrigger) if err != nil { a.respondWithError(w, err) return @@ -144,7 +144,7 @@ func (a *API) MessageQueueTriggerApiDelete(w http.ResponseWriter, r *http.Reques ns = metav1.NamespaceDefault } - err := a.fissionClient.Messagequeuetriggers(ns).Delete(name, &metav1.DeleteOptions{}) + err := a.fissionClient.MessageQueueTriggers(ns).Delete(name, &metav1.DeleteOptions{}) if err != nil { a.respondWithError(w, err) return diff --git a/controller/packageApi.go b/controller/packageApi.go index cbd7b3e9..2a8c53a2 100644 --- a/controller/packageApi.go +++ b/controller/packageApi.go @@ -25,7 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func (a *API) PackageApiList(w http.ResponseWriter, r *http.Request) { @@ -51,7 +51,7 @@ func (a *API) PackageApiCreate(w http.ResponseWriter, r *http.Request) { return } - var f tpr.Package + var f crd.Package err = json.Unmarshal(body, &f) if err != nil { a.respondWithError(w, err) @@ -130,7 +130,7 @@ func (a *API) PackageApiUpdate(w http.ResponseWriter, r *http.Request) { return } - var f tpr.Package + var f crd.Package err = json.Unmarshal(body, &f) if err != nil { a.respondWithError(w, err) diff --git a/controller/timeTriggerApi.go b/controller/timeTriggerApi.go index fd70dd4e..f1bb68c4 100644 --- a/controller/timeTriggerApi.go +++ b/controller/timeTriggerApi.go @@ -26,11 +26,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func (a *API) TimeTriggerApiList(w http.ResponseWriter, r *http.Request) { - triggers, err := a.fissionClient.Timetriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) + triggers, err := a.fissionClient.TimeTriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) if err != nil { a.respondWithError(w, err) return @@ -52,7 +52,7 @@ func (a *API) TimeTriggerApiCreate(w http.ResponseWriter, r *http.Request) { return } - var t tpr.Timetrigger + var t crd.TimeTrigger err = json.Unmarshal(body, &t) if err != nil { a.respondWithError(w, err) @@ -73,7 +73,7 @@ func (a *API) TimeTriggerApiCreate(w http.ResponseWriter, r *http.Request) { return } - tnew, err := a.fissionClient.Timetriggers(t.Metadata.Namespace).Create(&t) + tnew, err := a.fissionClient.TimeTriggers(t.Metadata.Namespace).Create(&t) if err != nil { a.respondWithError(w, err) return @@ -97,7 +97,7 @@ func (a *API) TimeTriggerApiGet(w http.ResponseWriter, r *http.Request) { ns = metav1.NamespaceDefault } - t, err := a.fissionClient.Timetriggers(ns).Get(name) + t, err := a.fissionClient.TimeTriggers(ns).Get(name) if err != nil { a.respondWithError(w, err) return @@ -122,7 +122,7 @@ func (a *API) TimeTriggerApiUpdate(w http.ResponseWriter, r *http.Request) { return } - var t tpr.Timetrigger + var t crd.TimeTrigger err = json.Unmarshal(body, &t) if err != nil { a.respondWithError(w, err) @@ -142,7 +142,7 @@ func (a *API) TimeTriggerApiUpdate(w http.ResponseWriter, r *http.Request) { return } - tnew, err := a.fissionClient.Timetriggers(t.Metadata.Namespace).Update(&t) + tnew, err := a.fissionClient.TimeTriggers(t.Metadata.Namespace).Update(&t) if err != nil { a.respondWithError(w, err) return @@ -164,7 +164,7 @@ func (a *API) TimeTriggerApiDelete(w http.ResponseWriter, r *http.Request) { ns = metav1.NamespaceDefault } - err := a.fissionClient.Timetriggers(ns).Delete(name, &metav1.DeleteOptions{}) + err := a.fissionClient.TimeTriggers(ns).Delete(name, &metav1.DeleteOptions{}) if err != nil { a.respondWithError(w, err) return diff --git a/controller/tpr2crdApi.go b/controller/tpr2crdApi.go new file mode 100644 index 00000000..9ee6d800 --- /dev/null +++ b/controller/tpr2crdApi.go @@ -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) +} diff --git a/controller/watchApi.go b/controller/watchApi.go index 8db50068..dc96cc80 100644 --- a/controller/watchApi.go +++ b/controller/watchApi.go @@ -25,11 +25,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func (a *API) WatchApiList(w http.ResponseWriter, r *http.Request) { - watches, err := a.fissionClient.Kuberneteswatchtriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) + watches, err := a.fissionClient.KubernetesWatchTriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) if err != nil { a.respondWithError(w, err) return @@ -51,7 +51,7 @@ func (a *API) WatchApiCreate(w http.ResponseWriter, r *http.Request) { return } - var watch tpr.Kuberneteswatchtrigger + var watch crd.KubernetesWatchTrigger err = json.Unmarshal(body, &watch) if err != nil { a.respondWithError(w, err) @@ -66,7 +66,7 @@ func (a *API) WatchApiCreate(w http.ResponseWriter, r *http.Request) { // TODO check for duplicate watches - wnew, err := a.fissionClient.Kuberneteswatchtriggers(watch.Metadata.Namespace).Create(&watch) + wnew, err := a.fissionClient.KubernetesWatchTriggers(watch.Metadata.Namespace).Create(&watch) if err != nil { a.respondWithError(w, err) return @@ -90,7 +90,7 @@ func (a *API) WatchApiGet(w http.ResponseWriter, r *http.Request) { ns = metav1.NamespaceDefault } - watch, err := a.fissionClient.Kuberneteswatchtriggers(ns).Get(name) + watch, err := a.fissionClient.KubernetesWatchTriggers(ns).Get(name) if err != nil { a.respondWithError(w, err) return @@ -118,7 +118,7 @@ func (a *API) WatchApiDelete(w http.ResponseWriter, r *http.Request) { ns = metav1.NamespaceDefault } - err := a.fissionClient.Kuberneteswatchtriggers(ns).Delete(name, &metav1.DeleteOptions{}) + err := a.fissionClient.KubernetesWatchTriggers(ns).Delete(name, &metav1.DeleteOptions{}) if err != nil { a.respondWithError(w, err) return diff --git a/tpr/client.go b/crd/client.go similarity index 63% rename from tpr/client.go rename to crd/client.go index 55fecb9c..e6ba8fba 100644 --- a/tpr/client.go +++ b/crd/client.go @@ -14,13 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +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" @@ -34,14 +35,14 @@ import ( type ( FissionClient struct { - tprClient *rest.RESTClient + 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, error) { +func GetKubernetesClient() (*rest.Config, *kubernetes.Clientset, *apiextensionsclient.Clientset, error) { var config *rest.Config var err error @@ -51,26 +52,31 @@ func GetKubernetesClient() (*rest.Config, *kubernetes.Clientset, error) { if len(kubeConfig) != 0 { config, err = clientcmd.BuildConfigFromFlags("", kubeConfig) if err != nil { - return nil, nil, err + return nil, nil, nil, err } } else { config, err = rest.InClusterConfig() if err != nil { - return nil, nil, err + return nil, nil, nil, err } } // creates the clientset clientset, err := kubernetes.NewForConfig(config) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - return config, clientset, nil + apiExtClientset, err := apiextensionsclient.NewForConfig(config) + if err != nil { + return nil, nil, nil, err + } + + return config, clientset, apiExtClientset, nil } -// GetTprClient gets a TPR client config -func GetTprClient(config *rest.Config) (*rest.RESTClient, error) { +// GetCrdClient gets a CRD client config +func GetCrdClient(config *rest.Config) (*rest.RESTClient, error) { // mutate config to add our types configureClient(config) @@ -78,14 +84,14 @@ func GetTprClient(config *rest.Config) (*rest.RESTClient, error) { return rest.RESTClientFor(config) } -// configureClient sets up a REST client for Fission TPR types. +// configureClient sets up a REST client for Fission CRD types. // -// This is copied from the client-go TPR example. (I don't understand +// 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 TPR types under a "group version" which we -// create for our TPRs types. +// 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", @@ -114,29 +120,29 @@ func configureClient(config *rest.Config) { ) scheme.AddKnownTypes( groupversion, - &Httptrigger{}, - &HttptriggerList{}, + &HTTPTrigger{}, + &HTTPTriggerList{}, &metav1.ListOptions{}, &metav1.DeleteOptions{}, ) scheme.AddKnownTypes( groupversion, - &Kuberneteswatchtrigger{}, - &KuberneteswatchtriggerList{}, + &KubernetesWatchTrigger{}, + &KubernetesWatchTriggerList{}, &metav1.ListOptions{}, &metav1.DeleteOptions{}, ) scheme.AddKnownTypes( groupversion, - &Timetrigger{}, - &TimetriggerList{}, + &TimeTrigger{}, + &TimeTriggerList{}, &metav1.ListOptions{}, &metav1.DeleteOptions{}, ) scheme.AddKnownTypes( groupversion, - &Messagequeuetrigger{}, - &MessagequeuetriggerList{}, + &MessageQueueTrigger{}, + &MessageQueueTriggerList{}, &metav1.ListOptions{}, &metav1.DeleteOptions{}, ) @@ -152,10 +158,10 @@ func configureClient(config *rest.Config) { schemeBuilder.AddToScheme(scheme.Scheme) } -func waitForTPRs(tprClient *rest.RESTClient) error { +func waitForCRDs(crdClient *rest.RESTClient) error { start := time.Now() for { - fi := MakeFunctionInterface(tprClient, metav1.NamespaceDefault) + fi := MakeFunctionInterface(crdClient, metav1.NamespaceDefault) _, err := fi.List(metav1.ListOptions{}) if err != nil { time.Sleep(100 * time.Millisecond) @@ -164,51 +170,51 @@ func waitForTPRs(tprClient *rest.RESTClient) error { } if time.Now().Sub(start) > 30*time.Second { - return errors.New("timeout waiting for TPRs") + return errors.New("timeout waiting for CRDs") } } } -func MakeFissionClient() (*FissionClient, *kubernetes.Clientset, error) { - config, kubeClient, err := GetKubernetesClient() +func MakeFissionClient() (*FissionClient, *kubernetes.Clientset, *apiextensionsclient.Clientset, error) { + config, kubeClient, apiExtClient, err := GetKubernetesClient() if err != nil { - return nil, nil, err + return nil, nil, nil, err } - tprClient, err := GetTprClient(config) + crdClient, err := GetCrdClient(config) if err != nil { - return nil, nil, err + return nil, nil, nil, err } fc := &FissionClient{ - tprClient: tprClient, + crdClient: crdClient, } - return fc, kubeClient, nil + return fc, kubeClient, apiExtClient, nil } func (fc *FissionClient) Functions(ns string) FunctionInterface { - return MakeFunctionInterface(fc.tprClient, ns) + return MakeFunctionInterface(fc.crdClient, ns) } func (fc *FissionClient) Environments(ns string) EnvironmentInterface { - return MakeEnvironmentInterface(fc.tprClient, ns) + return MakeEnvironmentInterface(fc.crdClient, ns) } -func (fc *FissionClient) Httptriggers(ns string) HttptriggerInterface { - return MakeHttptriggerInterface(fc.tprClient, ns) +func (fc *FissionClient) HTTPTriggers(ns string) HTTPTriggerInterface { + return MakeHTTPTriggerInterface(fc.crdClient, ns) } -func (fc *FissionClient) Kuberneteswatchtriggers(ns string) KuberneteswatchtriggerInterface { - return MakeKuberneteswatchtriggerInterface(fc.tprClient, ns) +func (fc *FissionClient) KubernetesWatchTriggers(ns string) KubernetesWatchTriggerInterface { + return MakeKubernetesWatchTriggerInterface(fc.crdClient, ns) } -func (fc *FissionClient) Timetriggers(ns string) TimetriggerInterface { - return MakeTimetriggerInterface(fc.tprClient, ns) +func (fc *FissionClient) TimeTriggers(ns string) TimeTriggerInterface { + return MakeTimeTriggerInterface(fc.crdClient, ns) } -func (fc *FissionClient) Messagequeuetriggers(ns string) MessagequeuetriggerInterface { - return MakeMessagequeuetriggerInterface(fc.tprClient, ns) +func (fc *FissionClient) MessageQueueTriggers(ns string) MessageQueueTriggerInterface { + return MakeMessageQueueTriggerInterface(fc.crdClient, ns) } func (fc *FissionClient) Packages(ns string) PackageInterface { - return MakePackageInterface(fc.tprClient, ns) + return MakePackageInterface(fc.crdClient, ns) } -func (fc *FissionClient) WaitForTPRs() { - waitForTPRs(fc.tprClient) +func (fc *FissionClient) WaitForCRDs() { + waitForCRDs(fc.crdClient) } -func (fc *FissionClient) GetTprClient() *rest.RESTClient { - return fc.tprClient +func (fc *FissionClient) GetCrdClient() *rest.RESTClient { + return fc.crdClient } diff --git a/crd/crd.go b/crd/crd.go new file mode 100644 index 00000000..3091e06a --- /dev/null +++ b/crd/crd.go @@ -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 +} diff --git a/tpr/tpr_test.go b/crd/crd_test.go similarity index 78% rename from tpr/tpr_test.go rename to crd/crd_test.go index 7e18c8a0..061ca649 100644 --- a/tpr/tpr_test.go +++ b/crd/crd_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +package crd import ( "log" @@ -34,7 +34,7 @@ func panicIf(err error) { } } -func functionTests(tprClient *rest.RESTClient) { +func functionTests(crdClient *rest.RESTClient) { // sample function object function := &Function{ TypeMeta: metav1.TypeMeta{ @@ -42,7 +42,8 @@ func functionTests(tprClient *rest.RESTClient) { APIVersion: "fission.io/v1", }, Metadata: metav1.ObjectMeta{ - Name: "hello", + Name: "hello", + Namespace: metav1.NamespaceDefault, }, Spec: fission.FunctionSpec{ Package: fission.FunctionPackageRef{ @@ -59,7 +60,7 @@ func functionTests(tprClient *rest.RESTClient) { } // Test function CRUD - fi := MakeFunctionInterface(tprClient, metav1.NamespaceDefault) + fi := MakeFunctionInterface(crdClient, metav1.NamespaceDefault) // cleanup from old crashed tests, ignore errors fi.Delete(function.Metadata.Name, nil) @@ -81,6 +82,7 @@ func functionTests(tprClient *rest.RESTClient) { log.Printf("f.Metadata = %#v", f.Metadata) // update + function.Metadata.ResourceVersion = f.Metadata.ResourceVersion function.Spec.Environment.Name = "yyy" f, err = fi.Update(function) panicIf(err) @@ -91,9 +93,9 @@ func functionTests(tprClient *rest.RESTClient) { fl, err := fi.List(metav1.ListOptions{}) panicIf(err) if len(fl.Items) != 1 { - log.Panicf("wrong count from list: %v", fl) + log.Panicf("wrong count from function list: %v", len(fl.Items)) } - if fl.Items[0].Spec.Environment.Name != function.Spec.Environment.Name { + if fl.Items[0].Spec.Environment.Name != f.Spec.Environment.Name { log.Panicf("bad object from list: %v", fl.Items[0]) } @@ -106,6 +108,7 @@ func functionTests(tprClient *rest.RESTClient) { panicIf(err) start := time.Now() + function.Metadata.ResourceVersion = "" f, err = fi.Create(function) panicIf(err) defer fi.Delete(f.Metadata.Name, nil) @@ -131,7 +134,7 @@ func functionTests(tprClient *rest.RESTClient) { } -func environmentTests(tprClient *rest.RESTClient) { +func environmentTests(crdClient *rest.RESTClient) { // sample environment object environment := &Environment{ TypeMeta: metav1.TypeMeta{ @@ -139,7 +142,8 @@ func environmentTests(tprClient *rest.RESTClient) { APIVersion: "fission.io/v1", }, Metadata: metav1.ObjectMeta{ - Name: "hello", + Name: "hello", + Namespace: metav1.NamespaceDefault, }, Spec: fission.EnvironmentSpec{ Runtime: fission.Runtime{ @@ -153,7 +157,7 @@ func environmentTests(tprClient *rest.RESTClient) { } // Test environment CRUD - ei := MakeEnvironmentInterface(tprClient, metav1.NamespaceDefault) + ei := MakeEnvironmentInterface(crdClient, metav1.NamespaceDefault) // cleanup from old crashed tests, ignore errors ei.Delete(environment.Metadata.Name, nil) @@ -173,6 +177,7 @@ func environmentTests(tprClient *rest.RESTClient) { } // update + environment.Metadata.ResourceVersion = e.Metadata.ResourceVersion environment.Spec.Runtime.Image = "www" e, err = ei.Update(environment) panicIf(err) @@ -181,9 +186,9 @@ func environmentTests(tprClient *rest.RESTClient) { el, err := ei.List(metav1.ListOptions{}) panicIf(err) if len(el.Items) != 1 { - log.Panicf("wrong count from list: %v", len(el.Items)) + log.Panicf("wrong count from environment list: %v", len(el.Items)) } - if el.Items[0].Spec.Runtime.Image != environment.Spec.Runtime.Image { + if el.Items[0].Spec.Runtime.Image != e.Spec.Runtime.Image { log.Panicf("bad object from list: %v", el.Items[0]) } @@ -196,6 +201,7 @@ func environmentTests(tprClient *rest.RESTClient) { panicIf(err) start := time.Now() + environment.Metadata.ResourceVersion = "" e, err = ei.Create(environment) panicIf(err) defer ei.Delete(e.Metadata.Name, nil) @@ -221,15 +227,16 @@ func environmentTests(tprClient *rest.RESTClient) { } -func httpTriggerTests(tprClient *rest.RESTClient) { +func httpTriggerTests(crdClient *rest.RESTClient) { // sample httpTrigger object - httpTrigger := &Httptrigger{ + httpTrigger := &HTTPTrigger{ TypeMeta: metav1.TypeMeta{ - Kind: "Httptrigger", + Kind: "HTTPTrigger", APIVersion: "fission.io/v1", }, Metadata: metav1.ObjectMeta{ - Name: "hello", + Name: "hello", + Namespace: metav1.NamespaceDefault, }, Spec: fission.HTTPTriggerSpec{ RelativeURL: "/hi", @@ -242,7 +249,7 @@ func httpTriggerTests(tprClient *rest.RESTClient) { } // Test httpTrigger CRUD - ei := MakeHttptriggerInterface(tprClient, metav1.NamespaceDefault) + ei := MakeHTTPTriggerInterface(crdClient, metav1.NamespaceDefault) // cleanup from old crashed tests, ignore errors ei.Delete(httpTrigger.Metadata.Name, nil) @@ -262,6 +269,7 @@ func httpTriggerTests(tprClient *rest.RESTClient) { } // update + httpTrigger.Metadata.ResourceVersion = e.Metadata.ResourceVersion httpTrigger.Spec.Method = "POST" e, err = ei.Update(httpTrigger) panicIf(err) @@ -270,9 +278,9 @@ func httpTriggerTests(tprClient *rest.RESTClient) { el, err := ei.List(metav1.ListOptions{}) panicIf(err) if len(el.Items) != 1 { - log.Panicf("wrong count from list: %v", el) + log.Panicf("wrong count from http trigger list: %v", len(el.Items)) } - if el.Items[0].Spec.Method != httpTrigger.Spec.Method { + if el.Items[0].Spec.Method != e.Spec.Method { log.Panicf("bad object from list: %v", el.Items[0]) } @@ -285,6 +293,7 @@ func httpTriggerTests(tprClient *rest.RESTClient) { panicIf(err) start := time.Now() + httpTrigger.Metadata.ResourceVersion = "" e, err = ei.Create(httpTrigger) panicIf(err) defer ei.Delete(e.Metadata.Name, nil) @@ -297,9 +306,9 @@ func httpTriggerTests(tprClient *rest.RESTClient) { log.Panicf("Didn't get watch event") } case ev := <-wi.ResultChan(): - obj, ok := ev.Object.(*Httptrigger) + obj, ok := ev.Object.(*HTTPTrigger) if !ok { - log.Panicf("Can't cast to Httptrigger") + log.Panicf("Can't cast to HTTPTrigger") } if obj.Spec.Method != httpTrigger.Spec.Method { log.Panicf("Bad object from watch: %#v", obj) @@ -310,15 +319,16 @@ func httpTriggerTests(tprClient *rest.RESTClient) { } -func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) { +func kubernetesWatchTriggerTests(crdClient *rest.RESTClient) { // sample kubernetesWatchTrigger object - kubernetesWatchTrigger := &Kuberneteswatchtrigger{ + kubernetesWatchTrigger := &KubernetesWatchTrigger{ TypeMeta: metav1.TypeMeta{ - Kind: "Kuberneteswatchtrigger", + Kind: "KubernetesWatchTrigger", APIVersion: "fission.io/v1", }, Metadata: metav1.ObjectMeta{ - Name: "hello", + Name: "hello", + Namespace: metav1.NamespaceDefault, }, Spec: fission.KubernetesWatchTriggerSpec{ Namespace: "foo", @@ -334,7 +344,7 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) { } // Test kubernetesWatchTrigger CRUD - ei := MakeKuberneteswatchtriggerInterface(tprClient, metav1.NamespaceDefault) + ei := MakeKubernetesWatchTriggerInterface(crdClient, metav1.NamespaceDefault) // cleanup from old crashed tests, ignore errors ei.Delete(kubernetesWatchTrigger.Metadata.Name, nil) @@ -354,6 +364,7 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) { } // update + kubernetesWatchTrigger.Metadata.ResourceVersion = e.Metadata.ResourceVersion kubernetesWatchTrigger.Spec.Type = "service" e, err = ei.Update(kubernetesWatchTrigger) panicIf(err) @@ -362,9 +373,9 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) { el, err := ei.List(metav1.ListOptions{}) panicIf(err) if len(el.Items) != 1 { - log.Panicf("wrong count from list: %v", el) + log.Panicf("wrong count from kubeWatcher list: %v", len(el.Items)) } - if el.Items[0].Spec.Type != kubernetesWatchTrigger.Spec.Type { + if el.Items[0].Spec.Type != e.Spec.Type { log.Panicf("bad object from list: %v", el.Items[0]) } @@ -377,6 +388,7 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) { panicIf(err) start := time.Now() + kubernetesWatchTrigger.Metadata.ResourceVersion = "" e, err = ei.Create(kubernetesWatchTrigger) panicIf(err) defer ei.Delete(e.Metadata.Name, nil) @@ -389,9 +401,9 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) { log.Panicf("Didn't get watch event") } case ev := <-wi.ResultChan(): - obj, ok := ev.Object.(*Kuberneteswatchtrigger) + obj, ok := ev.Object.(*KubernetesWatchTrigger) if !ok { - log.Panicf("Can't cast to Kuberneteswatchtrigger") + log.Panicf("Can't cast to KubernetesWatchTrigger") } if obj.Spec.Type != kubernetesWatchTrigger.Spec.Type { log.Panicf("Bad object from watch: %#v", obj) @@ -402,7 +414,7 @@ func kubernetesWatchTriggerTests(tprClient *rest.RESTClient) { } -func TestTpr(t *testing.T) { +func TestCrd(t *testing.T) { // skip test if no cluster available for testing kubeconfig := os.Getenv("KUBECONFIG") if len(kubeconfig) == 0 { @@ -412,22 +424,22 @@ func TestTpr(t *testing.T) { // Create the client config. Needs the KUBECONFIG env var to // point at a valid kubeconfig. - config, clientset, err := GetKubernetesClient() + config, _, apiExtClient, err := GetKubernetesClient() panicIf(err) // init our types - err = EnsureFissionTPRs(clientset) + err = EnsureFissionCRDs(apiExtClient) panicIf(err) - // rest client with knowledge about our tpr types - tprClient, err := GetTprClient(config) + // rest client with knowledge about our crd types + crdClient, err := GetCrdClient(config) panicIf(err) - err = waitForTPRs(tprClient) + err = waitForCRDs(crdClient) panicIf(err) - functionTests(tprClient) - environmentTests(tprClient) - httpTriggerTests(tprClient) - kubernetesWatchTriggerTests(tprClient) + functionTests(crdClient) + environmentTests(crdClient) + httpTriggerTests(crdClient) + kubernetesWatchTriggerTests(crdClient) } diff --git a/tpr/environment.go b/crd/environment.go similarity index 96% rename from tpr/environment.go rename to crd/environment.go index eb599368..feddd2b8 100644 --- a/tpr/environment.go +++ b/crd/environment.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +package crd import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -39,9 +39,9 @@ type ( } ) -func MakeEnvironmentInterface(tprClient *rest.RESTClient, namespace string) EnvironmentInterface { +func MakeEnvironmentInterface(crdClient *rest.RESTClient, namespace string) EnvironmentInterface { return &environmentClient{ - client: tprClient, + client: crdClient, namespace: namespace, } } diff --git a/tpr/function.go b/crd/function.go similarity index 96% rename from tpr/function.go rename to crd/function.go index 8ebeb82f..447cb03e 100644 --- a/tpr/function.go +++ b/crd/function.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +package crd import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -39,9 +39,9 @@ type ( } ) -func MakeFunctionInterface(tprClient *rest.RESTClient, namespace string) FunctionInterface { +func MakeFunctionInterface(crdClient *rest.RESTClient, namespace string) FunctionInterface { return &functionClient{ - client: tprClient, + client: crdClient, namespace: namespace, } } diff --git a/tpr/httptrigger.go b/crd/httptrigger.go similarity index 75% rename from tpr/httptrigger.go rename to crd/httptrigger.go index fc5f1779..2b10cef2 100644 --- a/tpr/httptrigger.go +++ b/crd/httptrigger.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +package crd import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -24,12 +24,12 @@ import ( ) type ( - HttptriggerInterface interface { - Create(*Httptrigger) (*Httptrigger, error) - Get(name string) (*Httptrigger, error) - Update(*Httptrigger) (*Httptrigger, error) + HTTPTriggerInterface interface { + Create(*HTTPTrigger) (*HTTPTrigger, error) + Get(name string) (*HTTPTrigger, error) + Update(*HTTPTrigger) (*HTTPTrigger, error) Delete(name string, options *metav1.DeleteOptions) error - List(opts metav1.ListOptions) (*HttptriggerList, error) + List(opts metav1.ListOptions) (*HTTPTriggerList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) } @@ -39,15 +39,15 @@ type ( } ) -func MakeHttptriggerInterface(tprClient *rest.RESTClient, namespace string) HttptriggerInterface { +func MakeHTTPTriggerInterface(crdClient *rest.RESTClient, namespace string) HTTPTriggerInterface { return &httpTriggerClient{ - client: tprClient, + client: crdClient, namespace: namespace, } } -func (c *httpTriggerClient) Create(obj *Httptrigger) (*Httptrigger, error) { - var result Httptrigger +func (c *httpTriggerClient) Create(obj *HTTPTrigger) (*HTTPTrigger, error) { + var result HTTPTrigger err := c.client.Post(). Resource("httptriggers"). Namespace(c.namespace). @@ -59,8 +59,8 @@ func (c *httpTriggerClient) Create(obj *Httptrigger) (*Httptrigger, error) { return &result, nil } -func (c *httpTriggerClient) Get(name string) (*Httptrigger, error) { - var result Httptrigger +func (c *httpTriggerClient) Get(name string) (*HTTPTrigger, error) { + var result HTTPTrigger err := c.client.Get(). Resource("httptriggers"). Namespace(c.namespace). @@ -72,8 +72,8 @@ func (c *httpTriggerClient) Get(name string) (*Httptrigger, error) { return &result, nil } -func (c *httpTriggerClient) Update(obj *Httptrigger) (*Httptrigger, error) { - var result Httptrigger +func (c *httpTriggerClient) Update(obj *HTTPTrigger) (*HTTPTrigger, error) { + var result HTTPTrigger err := c.client.Put(). Resource("httptriggers"). Namespace(c.namespace). @@ -96,8 +96,8 @@ func (c *httpTriggerClient) Delete(name string, opts *metav1.DeleteOptions) erro Error() } -func (c *httpTriggerClient) List(opts metav1.ListOptions) (*HttptriggerList, error) { - var result HttptriggerList +func (c *httpTriggerClient) List(opts metav1.ListOptions) (*HTTPTriggerList, error) { + var result HTTPTriggerList err := c.client.Get(). Namespace(c.namespace). Resource("httptriggers"). diff --git a/tpr/key.go b/crd/key.go similarity index 98% rename from tpr/key.go rename to crd/key.go index 2eacfa99..52f2edd6 100644 --- a/tpr/key.go +++ b/crd/key.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +package crd import ( "fmt" diff --git a/tpr/kubernetesWatchTrigger.go b/crd/kubernetesWatchTrigger.go similarity index 73% rename from tpr/kubernetesWatchTrigger.go rename to crd/kubernetesWatchTrigger.go index e679ba9c..84bb9226 100644 --- a/tpr/kubernetesWatchTrigger.go +++ b/crd/kubernetesWatchTrigger.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +package crd import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -24,12 +24,12 @@ import ( ) type ( - KuberneteswatchtriggerInterface interface { - Create(*Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error) - Get(name string) (*Kuberneteswatchtrigger, error) - Update(*Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error) + KubernetesWatchTriggerInterface interface { + Create(*KubernetesWatchTrigger) (*KubernetesWatchTrigger, error) + Get(name string) (*KubernetesWatchTrigger, error) + Update(*KubernetesWatchTrigger) (*KubernetesWatchTrigger, error) Delete(name string, options *metav1.DeleteOptions) error - List(opts metav1.ListOptions) (*KuberneteswatchtriggerList, error) + List(opts metav1.ListOptions) (*KubernetesWatchTriggerList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) } @@ -39,15 +39,15 @@ type ( } ) -func MakeKuberneteswatchtriggerInterface(tprClient *rest.RESTClient, namespace string) KuberneteswatchtriggerInterface { +func MakeKubernetesWatchTriggerInterface(crdClient *rest.RESTClient, namespace string) KubernetesWatchTriggerInterface { return &kubernetesWatchTriggerClient{ - client: tprClient, + client: crdClient, namespace: namespace, } } -func (c *kubernetesWatchTriggerClient) Create(obj *Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error) { - var result Kuberneteswatchtrigger +func (c *kubernetesWatchTriggerClient) Create(obj *KubernetesWatchTrigger) (*KubernetesWatchTrigger, error) { + var result KubernetesWatchTrigger err := c.client.Post(). Resource("kuberneteswatchtriggers"). Namespace(c.namespace). @@ -59,8 +59,8 @@ func (c *kubernetesWatchTriggerClient) Create(obj *Kuberneteswatchtrigger) (*Kub return &result, nil } -func (c *kubernetesWatchTriggerClient) Get(name string) (*Kuberneteswatchtrigger, error) { - var result Kuberneteswatchtrigger +func (c *kubernetesWatchTriggerClient) Get(name string) (*KubernetesWatchTrigger, error) { + var result KubernetesWatchTrigger err := c.client.Get(). Resource("kuberneteswatchtriggers"). Namespace(c.namespace). @@ -72,8 +72,8 @@ func (c *kubernetesWatchTriggerClient) Get(name string) (*Kuberneteswatchtrigger return &result, nil } -func (c *kubernetesWatchTriggerClient) Update(obj *Kuberneteswatchtrigger) (*Kuberneteswatchtrigger, error) { - var result Kuberneteswatchtrigger +func (c *kubernetesWatchTriggerClient) Update(obj *KubernetesWatchTrigger) (*KubernetesWatchTrigger, error) { + var result KubernetesWatchTrigger err := c.client.Put(). Resource("kuberneteswatchtriggers"). Namespace(c.namespace). @@ -96,8 +96,8 @@ func (c *kubernetesWatchTriggerClient) Delete(name string, opts *metav1.DeleteOp Error() } -func (c *kubernetesWatchTriggerClient) List(opts metav1.ListOptions) (*KuberneteswatchtriggerList, error) { - var result KuberneteswatchtriggerList +func (c *kubernetesWatchTriggerClient) List(opts metav1.ListOptions) (*KubernetesWatchTriggerList, error) { + var result KubernetesWatchTriggerList err := c.client.Get(). Namespace(c.namespace). Resource("kuberneteswatchtriggers"). diff --git a/tpr/messagequeuetrigger.go b/crd/messagequeuetrigger.go similarity index 64% rename from tpr/messagequeuetrigger.go rename to crd/messagequeuetrigger.go index e20335ff..8d84a124 100644 --- a/tpr/messagequeuetrigger.go +++ b/crd/messagequeuetrigger.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +package crd import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -24,30 +24,30 @@ import ( ) type ( - MessagequeuetriggerInterface interface { - Create(*Messagequeuetrigger) (*Messagequeuetrigger, error) - Get(name string) (*Messagequeuetrigger, error) - Update(*Messagequeuetrigger) (*Messagequeuetrigger, error) + MessageQueueTriggerInterface interface { + Create(*MessageQueueTrigger) (*MessageQueueTrigger, error) + Get(name string) (*MessageQueueTrigger, error) + Update(*MessageQueueTrigger) (*MessageQueueTrigger, error) Delete(name string, options *metav1.DeleteOptions) error - List(opts metav1.ListOptions) (*MessagequeuetriggerList, error) + List(opts metav1.ListOptions) (*MessageQueueTriggerList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) } - messagequeuetriggerClient struct { + messageQueueTriggerClient struct { client *rest.RESTClient namespace string } ) -func MakeMessagequeuetriggerInterface(tprClient *rest.RESTClient, namespace string) MessagequeuetriggerInterface { - return &messagequeuetriggerClient{ - client: tprClient, +func MakeMessageQueueTriggerInterface(crdClient *rest.RESTClient, namespace string) MessageQueueTriggerInterface { + return &messageQueueTriggerClient{ + client: crdClient, namespace: namespace, } } -func (fc *messagequeuetriggerClient) Create(f *Messagequeuetrigger) (*Messagequeuetrigger, error) { - var result Messagequeuetrigger +func (fc *messageQueueTriggerClient) Create(f *MessageQueueTrigger) (*MessageQueueTrigger, error) { + var result MessageQueueTrigger err := fc.client.Post(). Resource("messagequeuetriggers"). Namespace(fc.namespace). @@ -59,8 +59,8 @@ func (fc *messagequeuetriggerClient) Create(f *Messagequeuetrigger) (*Messageque return &result, nil } -func (fc *messagequeuetriggerClient) Get(name string) (*Messagequeuetrigger, error) { - var result Messagequeuetrigger +func (fc *messageQueueTriggerClient) Get(name string) (*MessageQueueTrigger, error) { + var result MessageQueueTrigger err := fc.client.Get(). Resource("messagequeuetriggers"). Namespace(fc.namespace). @@ -72,8 +72,8 @@ func (fc *messagequeuetriggerClient) Get(name string) (*Messagequeuetrigger, err return &result, nil } -func (fc *messagequeuetriggerClient) Update(f *Messagequeuetrigger) (*Messagequeuetrigger, error) { - var result Messagequeuetrigger +func (fc *messageQueueTriggerClient) Update(f *MessageQueueTrigger) (*MessageQueueTrigger, error) { + var result MessageQueueTrigger err := fc.client.Put(). Resource("messagequeuetriggers"). Namespace(fc.namespace). @@ -86,7 +86,7 @@ func (fc *messagequeuetriggerClient) Update(f *Messagequeuetrigger) (*Messageque return &result, nil } -func (fc *messagequeuetriggerClient) Delete(name string, opts *metav1.DeleteOptions) error { +func (fc *messageQueueTriggerClient) Delete(name string, opts *metav1.DeleteOptions) error { return fc.client.Delete(). Namespace(fc.namespace). Resource("messagequeuetriggers"). @@ -96,8 +96,8 @@ func (fc *messagequeuetriggerClient) Delete(name string, opts *metav1.DeleteOpti Error() } -func (fc *messagequeuetriggerClient) List(opts metav1.ListOptions) (*MessagequeuetriggerList, error) { - var result MessagequeuetriggerList +func (fc *messageQueueTriggerClient) List(opts metav1.ListOptions) (*MessageQueueTriggerList, error) { + var result MessageQueueTriggerList err := fc.client.Get(). Namespace(fc.namespace). Resource("messagequeuetriggers"). @@ -110,7 +110,7 @@ func (fc *messagequeuetriggerClient) List(opts metav1.ListOptions) (*Messagequeu return &result, nil } -func (fc *messagequeuetriggerClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { +func (fc *messageQueueTriggerClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { return fc.client.Get(). Prefix("watch"). Namespace(fc.namespace). diff --git a/tpr/package.go b/crd/package.go similarity index 96% rename from tpr/package.go rename to crd/package.go index 8457ae85..8db5541e 100644 --- a/tpr/package.go +++ b/crd/package.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +package crd import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -39,9 +39,9 @@ type ( } ) -func MakePackageInterface(tprClient *rest.RESTClient, namespace string) PackageInterface { +func MakePackageInterface(crdClient *rest.RESTClient, namespace string) PackageInterface { return &packageClient{ - client: tprClient, + client: crdClient, namespace: namespace, } } diff --git a/tpr/timetrigger.go b/crd/timetrigger.go similarity index 69% rename from tpr/timetrigger.go rename to crd/timetrigger.go index 3294dbc8..59850dfe 100644 --- a/tpr/timetrigger.go +++ b/crd/timetrigger.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +package crd import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -24,30 +24,30 @@ import ( ) type ( - TimetriggerInterface interface { - Create(*Timetrigger) (*Timetrigger, error) - Get(name string) (*Timetrigger, error) - Update(*Timetrigger) (*Timetrigger, error) + TimeTriggerInterface interface { + Create(*TimeTrigger) (*TimeTrigger, error) + Get(name string) (*TimeTrigger, error) + Update(*TimeTrigger) (*TimeTrigger, error) Delete(name string, options *metav1.DeleteOptions) error - List(opts metav1.ListOptions) (*TimetriggerList, error) + List(opts metav1.ListOptions) (*TimeTriggerList, error) Watch(opts metav1.ListOptions) (watch.Interface, error) } - timetriggerClient struct { + timeTriggerClient struct { client *rest.RESTClient namespace string } ) -func MakeTimetriggerInterface(tprClient *rest.RESTClient, namespace string) TimetriggerInterface { - return &timetriggerClient{ - client: tprClient, +func MakeTimeTriggerInterface(crdClient *rest.RESTClient, namespace string) TimeTriggerInterface { + return &timeTriggerClient{ + client: crdClient, namespace: namespace, } } -func (fc *timetriggerClient) Create(f *Timetrigger) (*Timetrigger, error) { - var result Timetrigger +func (fc *timeTriggerClient) Create(f *TimeTrigger) (*TimeTrigger, error) { + var result TimeTrigger err := fc.client.Post(). Resource("timetriggers"). Namespace(fc.namespace). @@ -59,8 +59,8 @@ func (fc *timetriggerClient) Create(f *Timetrigger) (*Timetrigger, error) { return &result, nil } -func (fc *timetriggerClient) Get(name string) (*Timetrigger, error) { - var result Timetrigger +func (fc *timeTriggerClient) Get(name string) (*TimeTrigger, error) { + var result TimeTrigger err := fc.client.Get(). Resource("timetriggers"). Namespace(fc.namespace). @@ -72,8 +72,8 @@ func (fc *timetriggerClient) Get(name string) (*Timetrigger, error) { return &result, nil } -func (fc *timetriggerClient) Update(f *Timetrigger) (*Timetrigger, error) { - var result Timetrigger +func (fc *timeTriggerClient) Update(f *TimeTrigger) (*TimeTrigger, error) { + var result TimeTrigger err := fc.client.Put(). Resource("timetriggers"). Namespace(fc.namespace). @@ -86,7 +86,7 @@ func (fc *timetriggerClient) Update(f *Timetrigger) (*Timetrigger, error) { return &result, nil } -func (fc *timetriggerClient) Delete(name string, opts *metav1.DeleteOptions) error { +func (fc *timeTriggerClient) Delete(name string, opts *metav1.DeleteOptions) error { return fc.client.Delete(). Namespace(fc.namespace). Resource("timetriggers"). @@ -96,8 +96,8 @@ func (fc *timetriggerClient) Delete(name string, opts *metav1.DeleteOptions) err Error() } -func (fc *timetriggerClient) List(opts metav1.ListOptions) (*TimetriggerList, error) { - var result TimetriggerList +func (fc *timeTriggerClient) List(opts metav1.ListOptions) (*TimeTriggerList, error) { + var result TimeTriggerList err := fc.client.Get(). Namespace(fc.namespace). Resource("timetriggers"). @@ -110,7 +110,7 @@ func (fc *timetriggerClient) List(opts metav1.ListOptions) (*TimetriggerList, er return &result, nil } -func (fc *timetriggerClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { +func (fc *timeTriggerClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { return fc.client.Get(). Prefix("watch"). Namespace(fc.namespace). diff --git a/tpr/types.go b/crd/types.go similarity index 73% rename from tpr/types.go rename to crd/types.go index 38e97659..40f232ce 100644 --- a/tpr/types.go +++ b/crd/types.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package tpr +package crd import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -24,14 +24,14 @@ import ( ) // -// To add a Fission TPR type: +// 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 EnsureFissionTPRs in tpr.go -// 7. Add tests to tpr_test.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 // @@ -78,68 +78,65 @@ type ( Items []Environment `json:"items"` } - // HTTP Triggers. (Something in the TPR reflection stuff wants - // it to be spelled "Httptrigger" not "HTTPTrigger" or even - // "HttpTrigger". Bleh.) - Httptrigger struct { + HTTPTrigger struct { metav1.TypeMeta `json:",inline"` Metadata metav1.ObjectMeta `json:"metadata"` Spec fission.HTTPTriggerSpec `json:"spec"` } - HttptriggerList struct { + HTTPTriggerList struct { metav1.TypeMeta `json:",inline"` Metadata metav1.ListMeta `json:"metadata"` - Items []Httptrigger `json:"items"` + Items []HTTPTrigger `json:"items"` } // Kubernetes Watches as triggers - Kuberneteswatchtrigger struct { + KubernetesWatchTrigger struct { metav1.TypeMeta `json:",inline"` Metadata metav1.ObjectMeta `json:"metadata"` Spec fission.KubernetesWatchTriggerSpec `json:"spec"` } - KuberneteswatchtriggerList struct { + KubernetesWatchTriggerList struct { metav1.TypeMeta `json:",inline"` Metadata metav1.ListMeta `json:"metadata"` - Items []Kuberneteswatchtrigger `json:"items"` + Items []KubernetesWatchTrigger `json:"items"` } // Time triggers - Timetrigger struct { + TimeTrigger struct { metav1.TypeMeta `json:",inline"` Metadata metav1.ObjectMeta `json:"metadata"` Spec fission.TimeTriggerSpec `json:"spec"` } - TimetriggerList struct { + TimeTriggerList struct { metav1.TypeMeta `json:",inline"` Metadata metav1.ListMeta `json:"metadata"` - Items []Timetrigger `json:"items"` + Items []TimeTrigger `json:"items"` } // Message Queue triggers - Messagequeuetrigger struct { + MessageQueueTrigger struct { metav1.TypeMeta `json:",inline"` Metadata metav1.ObjectMeta `json:"metadata"` Spec fission.MessageQueueTriggerSpec `json:"spec"` } - MessagequeuetriggerList struct { + MessageQueueTriggerList struct { metav1.TypeMeta `json:",inline"` Metadata metav1.ListMeta `json:"metadata"` - Items []Messagequeuetrigger `json:"items"` + Items []MessageQueueTrigger `json:"items"` } ) -// Each TPR type needs: +// Each CRD type needs: // GetObjectKind (to satisfy the Object interface) // -// In addition, each singular TPR type needs: +// In addition, each singular CRD type needs: // GetObjectMeta (to satisfy the ObjectMetaAccessor interface) // -// And each list TPR type needs: +// And each list CRD type needs: // GetListMeta (to satisfy the ListMetaAccessor interface) func (f *Function) GetObjectKind() schema.ObjectKind { @@ -148,16 +145,16 @@ func (f *Function) GetObjectKind() schema.ObjectKind { func (e *Environment) GetObjectKind() schema.ObjectKind { return &e.TypeMeta } -func (ht *Httptrigger) GetObjectKind() schema.ObjectKind { +func (ht *HTTPTrigger) GetObjectKind() schema.ObjectKind { return &ht.TypeMeta } -func (w *Kuberneteswatchtrigger) GetObjectKind() schema.ObjectKind { +func (w *KubernetesWatchTrigger) GetObjectKind() schema.ObjectKind { return &w.TypeMeta } -func (w *Timetrigger) GetObjectKind() schema.ObjectKind { +func (w *TimeTrigger) GetObjectKind() schema.ObjectKind { return &w.TypeMeta } -func (w *Messagequeuetrigger) GetObjectKind() schema.ObjectKind { +func (w *MessageQueueTrigger) GetObjectKind() schema.ObjectKind { return &w.TypeMeta } func (w *Package) GetObjectKind() schema.ObjectKind { @@ -170,16 +167,16 @@ func (f *Function) GetObjectMeta() metav1.Object { func (e *Environment) GetObjectMeta() metav1.Object { return &e.Metadata } -func (ht *Httptrigger) GetObjectMeta() metav1.Object { +func (ht *HTTPTrigger) GetObjectMeta() metav1.Object { return &ht.Metadata } -func (w *Kuberneteswatchtrigger) GetObjectMeta() metav1.Object { +func (w *KubernetesWatchTrigger) GetObjectMeta() metav1.Object { return &w.Metadata } -func (w *Timetrigger) GetObjectMeta() metav1.Object { +func (w *TimeTrigger) GetObjectMeta() metav1.Object { return &w.Metadata } -func (w *Messagequeuetrigger) GetObjectMeta() metav1.Object { +func (w *MessageQueueTrigger) GetObjectMeta() metav1.Object { return &w.Metadata } func (w *Package) GetObjectMeta() metav1.Object { @@ -192,16 +189,16 @@ func (fl *FunctionList) GetObjectKind() schema.ObjectKind { func (el *EnvironmentList) GetObjectKind() schema.ObjectKind { return &el.TypeMeta } -func (hl *HttptriggerList) GetObjectKind() schema.ObjectKind { +func (hl *HTTPTriggerList) GetObjectKind() schema.ObjectKind { return &hl.TypeMeta } -func (wl *KuberneteswatchtriggerList) GetObjectKind() schema.ObjectKind { +func (wl *KubernetesWatchTriggerList) GetObjectKind() schema.ObjectKind { return &wl.TypeMeta } -func (wl *TimetriggerList) GetObjectKind() schema.ObjectKind { +func (wl *TimeTriggerList) GetObjectKind() schema.ObjectKind { return &wl.TypeMeta } -func (wl *MessagequeuetriggerList) GetObjectKind() schema.ObjectKind { +func (wl *MessageQueueTriggerList) GetObjectKind() schema.ObjectKind { return &wl.TypeMeta } func (wl *PackageList) GetObjectKind() schema.ObjectKind { @@ -214,16 +211,16 @@ func (fl *FunctionList) GetListMeta() metav1.List { func (el *EnvironmentList) GetListMeta() metav1.List { return &el.Metadata } -func (hl *HttptriggerList) GetListMeta() metav1.List { +func (hl *HTTPTriggerList) GetListMeta() metav1.List { return &hl.Metadata } -func (wl *KuberneteswatchtriggerList) GetListMeta() metav1.List { +func (wl *KubernetesWatchTriggerList) GetListMeta() metav1.List { return &wl.Metadata } -func (wl *TimetriggerList) GetListMeta() metav1.List { +func (wl *TimeTriggerList) GetListMeta() metav1.List { return &wl.Metadata } -func (wl *MessagequeuetriggerList) GetListMeta() metav1.List { +func (wl *MessageQueueTriggerList) GetListMeta() metav1.List { return &wl.Metadata } func (wl *PackageList) GetListMeta() metav1.List { diff --git a/environments/fetcher/fetcher.go b/environments/fetcher/fetcher.go index a3a56a60..3d6f6260 100644 --- a/environments/fetcher/fetcher.go +++ b/environments/fetcher/fetcher.go @@ -17,11 +17,10 @@ import ( "github.com/mholt/archiver" "github.com/satori/go.uuid" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" "github.com/fission/fission" + "github.com/fission/fission/crd" storageSvcClient "github.com/fission/fission/storagesvc/client" - "github.com/fission/fission/tpr" ) type ( @@ -51,8 +50,7 @@ type ( Fetcher struct { sharedVolumePath string - fissionClient *tpr.FissionClient - kubeClient *kubernetes.Clientset + fissionClient *crd.FissionClient } ) @@ -63,14 +61,13 @@ const ( ) func MakeFetcher(sharedVolumePath string) *Fetcher { - fissionClient, kubeClient, err := tpr.MakeFissionClient() + fissionClient, _, _, err := crd.MakeFissionClient() if err != nil { return nil } return &Fetcher{ sharedVolumePath: sharedVolumePath, fissionClient: fissionClient, - kubeClient: kubeClient, } } diff --git a/fission/environment.go b/fission/environment.go index aa02315f..4f796449 100644 --- a/fission/environment.go +++ b/fission/environment.go @@ -25,7 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func envCreate(c *cli.Context) error { @@ -59,7 +59,7 @@ func envCreate(c *cli.Context) error { envVersion = 1 } - env := &tpr.Environment{ + env := &crd.Environment{ Metadata: metav1.ObjectMeta{ Name: envName, Namespace: metav1.NamespaceDefault, diff --git a/fission/function.go b/fission/function.go index 9e28decf..208bdbbd 100644 --- a/fission/function.go +++ b/fission/function.go @@ -37,9 +37,9 @@ import ( "github.com/fission/fission" "github.com/fission/fission/controller/client" + "github.com/fission/fission/crd" "github.com/fission/fission/fission/logdb" storageSvcClient "github.com/fission/fission/storagesvc/client" - "github.com/fission/fission/tpr" ) func fileSize(filePath string) int64 { @@ -113,7 +113,7 @@ func createPackage(client *client.Client, envName, srcArchiveName, deployArchive } pkgName := strings.ToLower(uuid.NewV4().String()) - pkg := &tpr.Package{ + pkg := &crd.Package{ Metadata: metav1.ObjectMeta{ Name: pkgName, Namespace: metav1.NamespaceDefault, @@ -200,7 +200,7 @@ func fnCreate(c *cli.Context) error { pkgMetadata := createPackage(client, envName, srcArchiveName, deployArchiveName, buildcmd) - function := &tpr.Function{ + function := &crd.Function{ Metadata: metav1.ObjectMeta{ Name: fnName, Namespace: metav1.NamespaceDefault, @@ -236,7 +236,7 @@ func fnCreate(c *cli.Context) error { method = "GET" } triggerName := uuid.NewV4().String() - ht := &tpr.Httptrigger{ + ht := &crd.HTTPTrigger{ Metadata: metav1.ObjectMeta{ Name: triggerName, Namespace: metav1.NamespaceDefault, diff --git a/fission/httptrigger.go b/fission/httptrigger.go index 708654cc..d83f7ca3 100644 --- a/fission/httptrigger.go +++ b/fission/httptrigger.go @@ -28,7 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) // returns one of http.Method* @@ -76,7 +76,7 @@ func htCreate(c *cli.Context) error { // just name triggers by uuid. triggerName := uuid.NewV4().String() - ht := &tpr.Httptrigger{ + ht := &crd.HTTPTrigger{ Metadata: metav1.ObjectMeta{ Name: triggerName, Namespace: metav1.NamespaceDefault, diff --git a/fission/main.go b/fission/main.go index ecb011c9..19bb2918 100644 --- a/fission/main.go +++ b/fission/main.go @@ -135,6 +135,14 @@ func main() { {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}, } + + 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{ {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}, @@ -143,6 +151,7 @@ func main() { {Name: "environment", Aliases: []string{"env"}, Usage: "Manage environments", Subcommands: envSubcommands}, {Name: "watch", Aliases: []string{"w"}, Usage: "Manage watches", Subcommands: wSubCommands}, {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) diff --git a/fission/migrate.go b/fission/migrate.go new file mode 100644 index 00000000..42892664 --- /dev/null +++ b/fission/migrate.go @@ -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 +} diff --git a/fission/mqtrigger.go b/fission/mqtrigger.go index be792805..f8e99aaa 100644 --- a/fission/mqtrigger.go +++ b/fission/mqtrigger.go @@ -26,8 +26,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" + "github.com/fission/fission/crd" "github.com/fission/fission/mqtrigger/messageQueue" - "github.com/fission/fission/tpr" ) func mqtCreate(c *cli.Context) error { @@ -72,7 +72,7 @@ func mqtCreate(c *cli.Context) error { checkMQTopicAvailability(mqType, topic, respTopic) - mqt := tpr.Messagequeuetrigger{ + mqt := crd.MessageQueueTrigger{ Metadata: metav1.ObjectMeta{ Name: mqtName, Namespace: metav1.NamespaceDefault, diff --git a/fission/timetrigger.go b/fission/timetrigger.go index 333c45a1..61009383 100644 --- a/fission/timetrigger.go +++ b/fission/timetrigger.go @@ -26,7 +26,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func ttCreate(c *cli.Context) error { @@ -45,7 +45,7 @@ func ttCreate(c *cli.Context) error { fatal("Need a cron spec like '0 30 * * *', '@every 1h30m', or '@hourly'; use --cron") } - tt := &tpr.Timetrigger{ + tt := &crd.TimeTrigger{ Metadata: metav1.ObjectMeta{ Name: name, Namespace: metav1.NamespaceDefault, diff --git a/fission/upgrade.go b/fission/upgrade.go index 23f8a7ae..37c322b8 100644 --- a/fission/upgrade.go +++ b/fission/upgrade.go @@ -15,7 +15,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" "github.com/fission/fission/v1" ) @@ -23,9 +23,9 @@ type ( V1FissionState struct { Functions []v1.Function `json:"functions"` Environments []v1.Environment `json:"environments"` - Httptriggers []v1.HTTPTrigger `json:"httptriggers"` + HTTPTriggers []v1.HTTPTrigger `json:"httptriggers"` Mqtriggers []v1.MessageQueueTrigger `json:"mqtriggers"` - Timetriggers []v1.TimeTrigger `json:"timetriggers"` + TimeTriggers []v1.TimeTrigger `json:"timetriggers"` Watches []v1.Watch `json:"watches"` NameChanges map[string]string `json:"namechanges"` } @@ -133,7 +133,7 @@ func upgradeDumpV1State(v1url string, filename string) { fmt.Println("Getting routes") resp = get(v1url + "/triggers/http") - err = json.Unmarshal(resp, &v1state.Httptriggers) + err = json.Unmarshal(resp, &v1state.HTTPTriggers) checkErr(err, "parse server response") fmt.Println("Getting message queue triggers") @@ -143,7 +143,7 @@ func upgradeDumpV1State(v1url string, filename string) { fmt.Println("Getting time triggers") resp = get(v1url + "/triggers/time") - err = json.Unmarshal(resp, &v1state.Timetriggers) + err = json.Unmarshal(resp, &v1state.TimeTriggers) checkErr(err, "parse server response") fmt.Println("Getting function list") @@ -163,7 +163,7 @@ func upgradeDumpV1State(v1url string, filename string) { funcMetaSet[f.Metadata] = true nr.trackName(f.Metadata.Name) } - for _, t := range v1state.Httptriggers { + for _, t := range v1state.HTTPTriggers { funcMetaSet[t.Function] = true nr.trackName(t.Metadata.Name) } @@ -175,7 +175,7 @@ func upgradeDumpV1State(v1url string, filename string) { funcMetaSet[t.Function] = true nr.trackName(t.Metadata.Name) } - for _, t := range v1state.Timetriggers { + for _, t := range v1state.TimeTriggers { funcMetaSet[t.Function] = true nr.trackName(t.Metadata.Name) } @@ -225,7 +225,7 @@ func upgradeDumpV1State(v1url string, filename string) { checkErr(err, "write file") 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 { @@ -235,7 +235,7 @@ func functionRefFromV1Metadata(m *v1.Metadata, nameRemap map[string]string) *fis } } -func tprMetadataFromV1Metadata(m *v1.Metadata, nameRemap map[string]string) *metav1.ObjectMeta { +func crdMetadataFromV1Metadata(m *v1.Metadata, nameRemap map[string]string) *metav1.ObjectMeta { return &metav1.ObjectMeta{ Name: nameRemap[m.Name], Namespace: metav1.NamespaceDefault, @@ -302,7 +302,7 @@ func upgradeRestoreState(c *cli.Context) error { }, Deployment: *archive, } - pkg, err := client.PackageCreate(&tpr.Package{ + pkg, err := client.PackageCreate(&crd.Package{ Metadata: metav1.ObjectMeta{ Name: pkgName, Namespace: metav1.NamespaceDefault, @@ -310,8 +310,8 @@ func upgradeRestoreState(c *cli.Context) error { Spec: pkgSpec, }) checkErr(err, fmt.Sprintf("create package %v", pkgName)) - _, err = client.FunctionCreate(&tpr.Function{ - Metadata: *tprMetadataFromV1Metadata(&f.Metadata, v1state.NameChanges), + _, err = client.FunctionCreate(&crd.Function{ + Metadata: *crdMetadataFromV1Metadata(&f.Metadata, v1state.NameChanges), Spec: fission.FunctionSpec{ Environment: pkgSpec.Environment, Package: fission.FunctionPackageRef{ @@ -329,8 +329,8 @@ func upgradeRestoreState(c *cli.Context) error { // create envs for _, e := range v1state.Environments { - _, err = client.EnvironmentCreate(&tpr.Environment{ - Metadata: *tprMetadataFromV1Metadata(&e.Metadata, v1state.NameChanges), + _, err = client.EnvironmentCreate(&crd.Environment{ + Metadata: *crdMetadataFromV1Metadata(&e.Metadata, v1state.NameChanges), Spec: fission.EnvironmentSpec{ Version: 1, Runtime: fission.Runtime{ @@ -342,9 +342,9 @@ func upgradeRestoreState(c *cli.Context) error { } // create httptriggers - for _, t := range v1state.Httptriggers { - _, err = client.HTTPTriggerCreate(&tpr.Httptrigger{ - Metadata: *tprMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), + for _, t := range v1state.HTTPTriggers { + _, err = client.HTTPTriggerCreate(&crd.HTTPTrigger{ + Metadata: *crdMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), Spec: fission.HTTPTriggerSpec{ RelativeURL: t.UrlPattern, Method: t.Method, @@ -356,8 +356,8 @@ func upgradeRestoreState(c *cli.Context) error { // create mqtriggers for _, t := range v1state.Mqtriggers { - _, err = client.MessageQueueTriggerCreate(&tpr.Messagequeuetrigger{ - Metadata: *tprMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), + _, err = client.MessageQueueTriggerCreate(&crd.MessageQueueTrigger{ + Metadata: *crdMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), Spec: fission.MessageQueueTriggerSpec{ FunctionReference: *functionRefFromV1Metadata(&t.Function, v1state.NameChanges), MessageQueueType: t.MessageQueueType, @@ -369,9 +369,9 @@ func upgradeRestoreState(c *cli.Context) error { } // create time triggers - for _, t := range v1state.Timetriggers { - _, err = client.TimeTriggerCreate(&tpr.Timetrigger{ - Metadata: *tprMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), + for _, t := range v1state.TimeTriggers { + _, err = client.TimeTriggerCreate(&crd.TimeTrigger{ + Metadata: *crdMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), Spec: fission.TimeTriggerSpec{ FunctionReference: *functionRefFromV1Metadata(&t.Function, v1state.NameChanges), Cron: t.Cron, @@ -382,8 +382,8 @@ func upgradeRestoreState(c *cli.Context) error { // create watches for _, t := range v1state.Watches { - _, err = client.WatchCreate(&tpr.Kuberneteswatchtrigger{ - Metadata: *tprMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), + _, err = client.WatchCreate(&crd.KubernetesWatchTrigger{ + Metadata: *crdMetadataFromV1Metadata(&t.Metadata, v1state.NameChanges), Spec: fission.KubernetesWatchTriggerSpec{ Namespace: t.Namespace, Type: t.ObjType, diff --git a/fission/watch.go b/fission/watch.go index e1457e00..00e3a96f 100644 --- a/fission/watch.go +++ b/fission/watch.go @@ -26,7 +26,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func wCreate(c *cli.Context) error { @@ -61,7 +61,7 @@ func wCreate(c *cli.Context) error { // automatically name watches watchName := uuid.NewV4().String() - w := &tpr.Kuberneteswatchtrigger{ + w := &crd.KubernetesWatchTrigger{ Metadata: metav1.ObjectMeta{ Name: watchName, Namespace: metav1.NamespaceDefault, diff --git a/glide.lock b/glide.lock index 12be4af6..a3f64efc 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 285f5f29e18f61b5b834a48ce815fd40e023aa55d51acbc2ac8033cd8267635d -updated: 2017-10-14T14:54:26.384349074+08:00 +hash: 7c938e591b0602b9fd3412aeffd3f1438fc77eaea80c8d9dd03431adb0e1e1c9 +updated: 2017-11-01T16:18:51.144141389+08:00 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 @@ -14,7 +14,7 @@ imports: - autorest/azure - autorest/date - name: github.com/coreos/etcd - version: 952eb4fadeef3f840bd7557544338c985d4ed0ef + version: 3ac54be402ffe4e6df505814456d4931508aaf21 subpackages: - client - name: github.com/davecgh/go-spew @@ -33,7 +33,7 @@ imports: - name: github.com/docopt/docopt-go version: 784ddc588536785e7299f7272f39101f7faccc3f - name: github.com/dsnet/compress - version: 0ae8e136a5df9e3caf6c0f69983608b07438411b + version: c4dbed65594871659ea7347a85e1b8dcd97b9990 subpackages: - bzip2 - bzip2/internal/sais @@ -84,7 +84,7 @@ imports: - name: github.com/gorilla/mux version: 24fca303ac6da784b9e8269f724ddeb0b2eea5e7 - name: github.com/graymeta/stow - version: da285caa6daa337ae04a9ac603dbaf9009ffe687 + version: 1c51f76db54d79c9db24cb131011632eb586196c subpackages: - local - name: github.com/hashicorp/golang-lru @@ -110,7 +110,7 @@ imports: - jlexer - jwriter - name: github.com/mholt/archiver - version: fe92d3d85a514d2752ad3b61ec412b598a2754f9 + version: 26cf5bb32d07aa4e8d0de15f56ce516f4641d7df - name: github.com/nats-io/go-nats version: 9147cfac69833916f9c73353ba43f939815c330a subpackages: @@ -127,9 +127,9 @@ imports: - name: github.com/nats-io/nuid version: 289cccf02c178dc782430d534e3c1f5b72af807f - name: github.com/nwaples/rardecode - version: f22b7ef81a0afac9ce1447d37e5ab8e99fbd2f73 + version: e06696f847aeda6f39a8f0b7cdff193b7690aef6 - name: github.com/pierrec/lz4 - version: 5a3d2245f97fc249850e7802e3c01fad02a1c316 + version: 08c27939df1bd95e881e2c2367a749964ad1fceb - name: github.com/pierrec/xxHash version: a0006b13c722f7f12368c00a3d3c2ae8a999a0c6 subpackages: @@ -139,7 +139,7 @@ imports: - name: github.com/PuerkitoBio/urlesc version: 5bd2802263f21d8788851d5305584c82a5c75d7e - name: github.com/robfig/cron - version: df38d32658d8788cd446ba74db4bb5375c4b0cb3 + version: 736158dc09e10f1911ca3a1e1b01f11b566ce5db - name: github.com/satori/go.uuid version: 879c5887cd475cd7864858769793b2ceb0d44feb - name: github.com/sirupsen/logrus @@ -213,10 +213,16 @@ imports: version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 - name: k8s.io/api version: 4b8fc5be9b77d91bbb6525d18591c43699a2b4e5 +- name: k8s.io/apiextensions-apiserver + version: fcd622fe88a4a6efcb5aea9e94ee87324ac1b036 subpackages: - - core/v1 + - pkg/apis/apiextensions + - pkg/apis/apiextensions/v1beta1 + - pkg/client/clientset/clientset + - pkg/client/clientset/clientset/scheme + - pkg/client/clientset/clientset/typed/apiextensions/v1beta1 - name: k8s.io/apimachinery - version: 1fd2e63a9a370677308a42f24fd40c86438afddf + version: 8ab5f3d8a330c2e9baaf84e39042db8d49034ae2 subpackages: - pkg/api/equality - pkg/api/errors diff --git a/glide.yaml b/glide.yaml index 529d8511..5ab39eef 100644 --- a/glide.yaml +++ b/glide.yaml @@ -31,8 +31,12 @@ import: - 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: 1fd2e63a9a370677308a42f24fd40c86438afddf + version: release-1.7 - package: github.com/influxdata/influxdb version: v1.2.0 subpackages: diff --git a/hack/runtests.sh b/hack/runtests.sh index c13a4290..de03690d 100755 --- a/hack/runtests.sh +++ b/hack/runtests.sh @@ -5,12 +5,16 @@ if [ ! -f ${KUBECONFIG} ] then unset KUBECONFIG else - K="kubectl --kubeconfig $KUBECONFIG" + K="kubectl --kubeconfig $KUBECONFIG --namespace default" if $K get configmap ok-to-destroy then - $K get function.fission.io -o name | cut -f2 -d'/' | xargs $K delete function.fission.io - $K get environment.fission.io -o name | cut -f2 -d'/' | xargs $K delete environment.fission.io - $K get httptrigger.fission.io -o name | cut -f2 -d'/' | xargs $K delete httptrigger.fission.io + $K delete functions --all + $K delete environments --all + $K delete httptriggers --all + $K delete kuberneteswatchtriggers --all + $K delete messagequeuetriggers --all + $K delete packages --all + $K delete timetriggers --all fi fi diff --git a/kubewatcher/kubewatcher.go b/kubewatcher/kubewatcher.go index cdab6262..700998fc 100644 --- a/kubewatcher/kubewatcher.go +++ b/kubewatcher/kubewatcher.go @@ -36,8 +36,8 @@ import ( "k8s.io/client-go/kubernetes" "github.com/fission/fission" + "github.com/fission/fission/crd" "github.com/fission/fission/publisher" - "github.com/fission/fission/tpr" ) type requestType int @@ -56,7 +56,7 @@ type ( } watchSubscription struct { - watch tpr.Kuberneteswatchtrigger + watch crd.KubernetesWatchTrigger kubeWatch watch.Interface lastResourceVersion string stopped *int32 @@ -66,7 +66,7 @@ type ( kubeWatcherRequest struct { requestType - watches []tpr.Kuberneteswatchtrigger + watches []crd.KubernetesWatchTrigger responseChannel chan *kubeWatcherResponse } kubeWatcherResponse struct { @@ -85,7 +85,7 @@ func MakeKubeWatcher(kubernetesClient *kubernetes.Clientset, publisher publisher return kw } -func (kw *KubeWatcher) Sync(watches []tpr.Kuberneteswatchtrigger) error { +func (kw *KubeWatcher) Sync(watches []crd.KubernetesWatchTrigger) error { req := &kubeWatcherRequest{ requestType: SYNC, watches: watches, @@ -145,7 +145,7 @@ func printKubernetesObject(obj runtime.Object, w io.Writer) error { 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 err error var watchTimeoutSec int64 = 120 @@ -174,7 +174,7 @@ func createKubernetesWatch(kubeClient *kubernetes.Clientset, w *tpr.Kuberneteswa 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) ws, err := MakeWatchSubscription(w, kw.kubernetesClient, kw.publisher) if err != nil { @@ -184,7 +184,7 @@ func (kw *KubeWatcher) addWatch(w *tpr.Kuberneteswatchtrigger) error { 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) ws, ok := kw.watches[w.Metadata.UID] if !ok { @@ -211,7 +211,7 @@ func (kw *KubeWatcher) removeWatch(w *tpr.Kuberneteswatchtrigger) error { // 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 ws := &watchSubscription{ watch: *w, diff --git a/kubewatcher/main.go b/kubewatcher/main.go index 601a0f55..b99e898f 100644 --- a/kubewatcher/main.go +++ b/kubewatcher/main.go @@ -17,12 +17,12 @@ limitations under the License. package kubewatcher import ( + "github.com/fission/fission/crd" "github.com/fission/fission/publisher" - "github.com/fission/fission/tpr" ) func Start(routerUrl string) error { - fissionClient, kubeClient, err := tpr.MakeFissionClient() + fissionClient, kubeClient, _, err := crd.MakeFissionClient() if err != nil { return err } diff --git a/kubewatcher/watchSync.go b/kubewatcher/watchSync.go index 166a2840..14fb9ed3 100644 --- a/kubewatcher/watchSync.go +++ b/kubewatcher/watchSync.go @@ -22,17 +22,17 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) type ( WatchSync struct { - client *tpr.FissionClient + client *crd.FissionClient kubeWatcher *KubeWatcher } ) -func MakeWatchSync(client *tpr.FissionClient, kubeWatcher *KubeWatcher) *WatchSync { +func MakeWatchSync(client *crd.FissionClient, kubeWatcher *KubeWatcher) *WatchSync { ws := &WatchSync{ client: client, kubeWatcher: kubeWatcher, @@ -44,7 +44,7 @@ func MakeWatchSync(client *tpr.FissionClient, kubeWatcher *KubeWatcher) *WatchSy func (ws *WatchSync) syncSvc() { // TODO watch instead of polling for { - watches, err := ws.client.Kuberneteswatchtriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) + watches, err := ws.client.KubernetesWatchTriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) if err != nil { log.Fatalf("Failed to get Kubernetes watch trigger list: %v", err) } diff --git a/mqtrigger/main.go b/mqtrigger/main.go index e5219ed5..81fea523 100644 --- a/mqtrigger/main.go +++ b/mqtrigger/main.go @@ -17,15 +17,15 @@ limitations under the License. package messagequeue import ( + "log" "os" + "github.com/fission/fission/crd" "github.com/fission/fission/mqtrigger/messageQueue" - "github.com/fission/fission/tpr" - "log" ) func Start(routerUrl string) error { - fissionClient, _, err := tpr.MakeFissionClient() + fissionClient, _, _, err := crd.MakeFissionClient() if err != nil { log.Fatalf("Failed to get fission client: %v", err) } diff --git a/mqtrigger/messageQueue/messageQueue.go b/mqtrigger/messageQueue/messageQueue.go index d5d73ae2..29a00c9d 100644 --- a/mqtrigger/messageQueue/messageQueue.go +++ b/mqtrigger/messageQueue/messageQueue.go @@ -23,7 +23,7 @@ import ( log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) const ( @@ -47,7 +47,7 @@ type ( } MessageQueue interface { - subscribe(trigger *tpr.Messagequeuetrigger) (messageQueueSubscription, error) + subscribe(trigger *crd.MessageQueueTrigger) (messageQueueSubscription, error) unsubscribe(triggerSub messageQueueSubscription) error } @@ -55,12 +55,12 @@ type ( reqChan chan request mqCfg MessageQueueConfig triggers map[string]*triggerSubscription - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient messageQueue MessageQueue } triggerSubscription struct { - trigger tpr.Messagequeuetrigger + trigger crd.MessageQueueTrigger subscription messageQueueSubscription } @@ -75,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 err error @@ -105,7 +105,7 @@ func (mqt *MessageQueueTriggerManager) service() { switch req.requestType { case ADD_TRIGGER: var err error - k := tpr.CacheKey(&req.triggerSub.trigger.Metadata) + k := crd.CacheKey(&req.triggerSub.trigger.Metadata) if _, ok := mqt.triggers[k]; ok { err = errors.New("Trigger already exists") } else { @@ -119,7 +119,7 @@ func (mqt *MessageQueueTriggerManager) service() { } req.respChan <- response{triggers: ©Triggers} case DELETE_TRIGGER: - delete(mqt.triggers, tpr.CacheKey(&req.triggerSub.trigger.Metadata)) + delete(mqt.triggers, crd.CacheKey(&req.triggerSub.trigger.Metadata)) } } } @@ -149,7 +149,7 @@ func (mqt *MessageQueueTriggerManager) delTrigger(m *metav1.ObjectMeta) { mqt.reqChan <- request{ requestType: DELETE_TRIGGER, triggerSub: &triggerSubscription{ - trigger: tpr.Messagequeuetrigger{ + trigger: crd.MessageQueueTrigger{ Metadata: *m, }, }, @@ -159,14 +159,14 @@ func (mqt *MessageQueueTriggerManager) delTrigger(m *metav1.ObjectMeta) { func (mqt *MessageQueueTriggerManager) syncTriggers() { for { // get new set of triggers - newTriggers, err := mqt.fissionClient.Messagequeuetriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) + newTriggers, err := mqt.fissionClient.MessageQueueTriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) if err != nil { 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 { newTrigger := &newTriggers.Items[index] - newTriggerMap[tpr.CacheKey(&newTrigger.Metadata)] = newTrigger + newTriggerMap[crd.CacheKey(&newTrigger.Metadata)] = newTrigger } // get current set of triggers diff --git a/mqtrigger/messageQueue/nats.go b/mqtrigger/messageQueue/nats.go index 33330135..d2fde7a9 100644 --- a/mqtrigger/messageQueue/nats.go +++ b/mqtrigger/messageQueue/nats.go @@ -29,7 +29,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) const ( @@ -58,7 +58,7 @@ func makeNatsMessageQueue(routerUrl string, mqCfg MessageQueueConfig) (MessageQu 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 if !isTopicValidForNats(subj) { @@ -91,7 +91,7 @@ func isTopicValidForNats(topic string) bool { 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) { // Support other function ref types diff --git a/poolmgr/api.go b/poolmgr/api.go index 79bd9643..d4e09ee8 100644 --- a/poolmgr/api.go +++ b/poolmgr/api.go @@ -33,7 +33,7 @@ import ( "github.com/fission/fission" "github.com/fission/fission/cache" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) type ( @@ -49,16 +49,16 @@ type ( Poolmgr struct { gpm *GenericPoolManager - functionEnv *cache.Cache // map[string]tpr.Environment + functionEnv *cache.Cache // map[string]crd.Environment fsCache *functionServiceCache - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient fsCreateChannels map[string]*sync.WaitGroup // xxx no channels here, rename this requestChan chan *createFuncServiceRequest } ) -func MakePoolmgr(gpm *GenericPoolManager, fissionClient *tpr.FissionClient, fissionNs string, fsCache *functionServiceCache) *Poolmgr { +func MakePoolmgr(gpm *GenericPoolManager, fissionClient *crd.FissionClient, fissionNs string, fsCache *functionServiceCache) *Poolmgr { poolMgr := &Poolmgr{ gpm: gpm, functionEnv: cache.MakeCache(10*time.Second, 0), @@ -83,13 +83,13 @@ func (poolMgr *Poolmgr) serveCreateFuncServices() { m := req.funcMeta // Cache miss -- is this first one to request the func? - wg, found := poolMgr.fsCreateChannels[tpr.CacheKey(m)] + wg, found := poolMgr.fsCreateChannels[crd.CacheKey(m)] if !found { // create a waitgroup for other requests for // the same function to wait on wg := &sync.WaitGroup{} wg.Add(1) - poolMgr.fsCreateChannels[tpr.CacheKey(m)] = wg + poolMgr.fsCreateChannels[crd.CacheKey(m)] = wg // launch a goroutine for each request, to parallelize // the specialization of different functions @@ -99,7 +99,7 @@ func (poolMgr *Poolmgr) serveCreateFuncServices() { address: address, err: err, } - delete(poolMgr.fsCreateChannels, tpr.CacheKey(m)) + delete(poolMgr.fsCreateChannels, crd.CacheKey(m)) wg.Done() }() } else { @@ -149,13 +149,13 @@ func (poolMgr *Poolmgr) getServiceForFunctionApi(w http.ResponseWriter, r *http. w.Write([]byte(serviceName)) } -func (poolMgr *Poolmgr) getFunctionEnv(m *metav1.ObjectMeta) (*tpr.Environment, error) { - var env *tpr.Environment +func (poolMgr *Poolmgr) getFunctionEnv(m *metav1.ObjectMeta) (*crd.Environment, error) { + var env *crd.Environment // Cached ? - result, err := poolMgr.functionEnv.Get(tpr.CacheKey(m)) + result, err := poolMgr.functionEnv.Get(crd.CacheKey(m)) if err == nil { - env = result.(*tpr.Environment) + env = result.(*crd.Environment) return env, nil } @@ -173,7 +173,7 @@ func (poolMgr *Poolmgr) getFunctionEnv(m *metav1.ObjectMeta) (*tpr.Environment, } // cache for future lookups - poolMgr.functionEnv.Set(tpr.CacheKey(m), env) + poolMgr.functionEnv.Set(crd.CacheKey(m), env) return env, nil } diff --git a/poolmgr/functionServiceCache.go b/poolmgr/functionServiceCache.go index 296a6c50..c4ea0ccb 100644 --- a/poolmgr/functionServiceCache.go +++ b/poolmgr/functionServiceCache.go @@ -24,7 +24,7 @@ import ( "github.com/fission/fission" "github.com/fission/fission/cache" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) type fscRequestType int @@ -39,7 +39,7 @@ const ( type ( funcSvc struct { function *metav1.ObjectMeta // function this pod/service is for - environment *tpr.Environment // function's environment + environment *crd.Environment // function's environment address string // Host:Port or IP:Port that the function's service can be reached at. podName string // pod name (within the function namespace) @@ -94,7 +94,7 @@ func (fsc *functionServiceCache) service() { pods := make([]string, 0) for podNameI, mI := range byPodCopy { m := mI.(metav1.ObjectMeta) - fsvcI, err := fsc.byFunction.Get(tpr.CacheKey(&m)) + fsvcI, err := fsc.byFunction.Get(crd.CacheKey(&m)) if err != nil { resp.error = err } else { @@ -123,7 +123,7 @@ func (fsc *functionServiceCache) service() { } func (fsc *functionServiceCache) GetByFunction(m *metav1.ObjectMeta) (*funcSvc, error) { - key := tpr.CacheKey(m) + key := crd.CacheKey(m) fsvcI, err := fsc.byFunction.Get(key) if err != nil { @@ -140,7 +140,7 @@ func (fsc *functionServiceCache) GetByFunction(m *metav1.ObjectMeta) (*funcSvc, // TODO: error should be second return func (fsc *functionServiceCache) Add(fsvc funcSvc) (error, *funcSvc) { - err, existing := fsc.byFunction.Set(tpr.CacheKey(fsvc.function), &fsvc) + err, existing := fsc.byFunction.Set(crd.CacheKey(fsvc.function), &fsvc) if err != nil { if existing != nil { f := existing.(*funcSvc) @@ -199,7 +199,7 @@ func (fsc *functionServiceCache) _touchByAddress(address string) error { return err } m := mI.(metav1.ObjectMeta) - fsvcI, err := fsc.byFunction.Get(tpr.CacheKey(&m)) + fsvcI, err := fsc.byFunction.Get(crd.CacheKey(&m)) if err != nil { return err } @@ -228,7 +228,7 @@ func (fsc *functionServiceCache) _deleteByPod(podName string, minAge time.Durati return false, err } m := mI.(metav1.ObjectMeta) - fsvcI, err := fsc.byFunction.Get(tpr.CacheKey(&m)) + fsvcI, err := fsc.byFunction.Get(crd.CacheKey(&m)) if err != nil { return false, err } @@ -238,7 +238,7 @@ func (fsc *functionServiceCache) _deleteByPod(podName string, minAge time.Durati return false, nil } - fsc.byFunction.Delete(tpr.CacheKey(&m)) + fsc.byFunction.Delete(crd.CacheKey(&m)) fsc.byAddress.Delete(fsvc.address) fsc.byPod.Delete(podName) return true, nil diff --git a/poolmgr/functionServiceCache_test.go b/poolmgr/functionServiceCache_test.go index 4386c3ac..7c1bd8d4 100644 --- a/poolmgr/functionServiceCache_test.go +++ b/poolmgr/functionServiceCache_test.go @@ -8,7 +8,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func TestFunctionServiceCache(t *testing.T) { @@ -25,7 +25,7 @@ func TestFunctionServiceCache(t *testing.T) { Name: "foo", UID: "1212", }, - environment: &tpr.Environment{ + environment: &crd.Environment{ Metadata: metav1.ObjectMeta{ Name: "foo-env", UID: "2323", diff --git a/poolmgr/gp.go b/poolmgr/gp.go index f19de636..61926bd4 100644 --- a/poolmgr/gp.go +++ b/poolmgr/gp.go @@ -40,10 +40,10 @@ import ( "k8s.io/client-go/pkg/apis/extensions/v1beta1" "github.com/fission/fission" + "github.com/fission/fission/crd" "github.com/fission/fission/environments/fetcher" fetcherClient "github.com/fission/fission/environments/fetcher/client" "github.com/fission/fission/logger" - "github.com/fission/fission/tpr" ) const POOLMGR_INSTANCEID_LABEL string = "poolmgrInstanceId" @@ -51,7 +51,7 @@ const POD_PHASE_RUNNING string = "Running" type ( GenericPool struct { - env *tpr.Environment + env *crd.Environment replicas int32 // num idle pods deployment *v1beta1.Deployment // kubernetes deployment namespace string // namespace to keep our resources @@ -64,7 +64,7 @@ type ( fetcherImagePullPolicy apiv1.PullPolicy runtimeImagePullPolicy apiv1.PullPolicy // pull policy for generic pool to created env deployment kubernetesClient *kubernetes.Clientset - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient instanceId string // poolmgr instance id labelsForPool map[string]string requestChannel chan *choosePodRequest @@ -94,9 +94,9 @@ func getImagePullPolicy(policy string) apiv1.PullPolicy { } func MakeGenericPool( - fissionClient *tpr.FissionClient, + fissionClient *crd.FissionClient, kubernetesClient *kubernetes.Clientset, - env *tpr.Environment, + env *crd.Environment, initialReplicas int32, namespace string, fsCache *functionServiceCache, diff --git a/poolmgr/gpm.go b/poolmgr/gpm.go index 9c8ead45..5589ccf5 100644 --- a/poolmgr/gpm.go +++ b/poolmgr/gpm.go @@ -24,7 +24,7 @@ import ( "k8s.io/client-go/kubernetes" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) type requestType int @@ -39,15 +39,15 @@ type ( pools map[string]*GenericPool kubernetesClient *kubernetes.Clientset namespace string - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient fsCache *functionServiceCache instanceId string requestChannel chan *request } request struct { requestType - env *tpr.Environment - envList []tpr.Environment + env *crd.Environment + envList []crd.Environment responseChannel chan *response } response struct { @@ -57,7 +57,7 @@ type ( ) func MakeGenericPoolManager( - fissionClient *tpr.FissionClient, + fissionClient *crd.FissionClient, kubernetesClient *kubernetes.Clientset, fissionNamespace string, functionNamespace string, @@ -85,7 +85,7 @@ func (gpm *GenericPoolManager) service() { switch req.requestType { case GET_POOL: var err error - pool, ok := gpm.pools[tpr.CacheKey(&req.env.Metadata)] + pool, ok := gpm.pools[crd.CacheKey(&req.env.Metadata)] if !ok { var poolSize int32 = 3 // TODO configurable/autoscalable switch req.env.Spec.AllowedFunctionsPerContainer { @@ -100,13 +100,13 @@ func (gpm *GenericPoolManager) service() { req.responseChannel <- &response{error: err} continue } - gpm.pools[tpr.CacheKey(&req.env.Metadata)] = pool + gpm.pools[crd.CacheKey(&req.env.Metadata)] = pool } req.responseChannel <- &response{pool: pool} case CLEANUP_POOLS: latestEnvSet := make(map[string]bool) for _, env := range req.envList { - latestEnvSet[tpr.CacheKey(&env.Metadata)] = true + latestEnvSet[crd.CacheKey(&env.Metadata)] = true } for key, pool := range gpm.pools { _, ok := latestEnvSet[key] @@ -124,7 +124,7 @@ func (gpm *GenericPoolManager) service() { } } -func (gpm *GenericPoolManager) GetPool(env *tpr.Environment) (*GenericPool, error) { +func (gpm *GenericPoolManager) GetPool(env *crd.Environment) (*GenericPool, error) { c := make(chan *response) gpm.requestChannel <- &request{ requestType: GET_POOL, @@ -135,7 +135,7 @@ func (gpm *GenericPoolManager) GetPool(env *tpr.Environment) (*GenericPool, erro return resp.pool, resp.error } -func (gpm *GenericPoolManager) CleanupPools(envs []tpr.Environment) { +func (gpm *GenericPoolManager) CleanupPools(envs []crd.Environment) { gpm.requestChannel <- &request{ requestType: CLEANUP_POOLS, envList: envs, diff --git a/poolmgr/poolmgr.go b/poolmgr/poolmgr.go index 75c12ff9..7d3992a1 100644 --- a/poolmgr/poolmgr.go +++ b/poolmgr/poolmgr.go @@ -21,12 +21,12 @@ import ( "github.com/dchest/uniuri" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) // Start the poolmgr service. func StartPoolmgr(fissionNamespace string, functionNamespace string, port int) error { - fissionClient, kubernetesClient, err := tpr.MakeFissionClient() + fissionClient, kubernetesClient, _, err := crd.MakeFissionClient() if err != nil { log.Printf("Failed to get kubernetes client: %v", err) return err diff --git a/poolmgr/poolmgr_test.go b/poolmgr/poolmgr_test.go index b074fa7a..722371f1 100644 --- a/poolmgr/poolmgr_test.go +++ b/poolmgr/poolmgr_test.go @@ -39,14 +39,14 @@ import ( apiv1 "k8s.io/client-go/pkg/api/v1" "github.com/fission/fission" + "github.com/fission/fission/crd" "github.com/fission/fission/poolmgr/client" - "github.com/fission/fission/tpr" ) // return the number of pods in the given namespace matching the given labels func countPods(kubeClient *kubernetes.Clientset, ns string, labelz map[string]string) int { pods, err := kubeClient.Pods(ns).List(metav1.ListOptions{ - LabelSelector: labels.Set(labelz).AsSelector(), + LabelSelector: labels.Set(labelz).AsSelector().String(), }) if err != nil { log.Panicf("Failed to list pods: %v", err) @@ -120,8 +120,8 @@ func TestPoolmgr(t *testing.T) { } // connect to k8s - // and get TPR client - fissionClient, kubeClient, err := tpr.MakeFissionClient() + // and get CRD client + fissionClient, kubeClient, apiExtClient, err := crd.MakeFissionClient() if err != nil { log.Panicf("failed to connect: %v", err) } @@ -133,16 +133,16 @@ func TestPoolmgr(t *testing.T) { createTestNamespace(kubeClient, functionNs) defer kubeClient.Namespaces().Delete(functionNs, nil) - // make sure TPR types exist on cluster - err = tpr.EnsureFissionTPRs(kubeClient) + // make sure CRD types exist on cluster + err = crd.EnsureFissionCRDs(apiExtClient) if err != nil { - log.Panicf("failed to ensure tprs: %v", err) + log.Panicf("failed to ensure crds: %v", err) } - fissionClient.WaitForTPRs() + fissionClient.WaitForCRDs() // create an env on the cluster - env, err := fissionClient.Environments(fissionNs).Create(&tpr.Environment{ - Metadata: metametav1.ObjectMeta{ + env, err := fissionClient.Environments(fissionNs).Create(&crd.Environment{ + Metadata: metav1.ObjectMeta{ Name: "nodejs", Namespace: fissionNs, }, @@ -173,37 +173,47 @@ func TestPoolmgr(t *testing.T) { // waitForPool(functionNs, "nodejs") time.Sleep(6 * time.Second) + envRef := fission.EnvironmentReference{ + Namespace: env.Metadata.Namespace, + Name: env.Metadata.Name, + } + + deployment := fission.Archive{ + Type: fission.ArchiveTypeLiteral, + Literal: []byte(`module.exports = async function(context) { return { status: 200, body: "Hello, world!\n" }; }`), + } + // create a package - p := &tpr.Package{ - Metadata: metametav1.ObjectMeta{ + p := &crd.Package{ + Metadata: metav1.ObjectMeta{ Name: "hello", Namespace: fissionNs, }, Spec: fission.PackageSpec{ - Type: fission.PackageTypeLiteral, - Literal: []byte(`module.exports = async function(context) { return { status: 200, body: "Hello, world!\n" }; }`), + Environment: envRef, + Deployment: deployment, }, } - _, err = fissionClient.Packages(fissionNs).Create(p) + p, err = fissionClient.Packages(fissionNs).Create(p) if err != nil { log.Panicf("failed to create package: %v", err) } // create a function - f := &tpr.Function{ - Metadata: metametav1.ObjectMeta{ + f := &crd.Function{ + Metadata: metav1.ObjectMeta{ Name: "hello", Namespace: fissionNs, }, Spec: fission.FunctionSpec{ - Source: fission.FunctionPackageRef{}, - Deployment: fission.FunctionPackageRef{ + Environment: envRef, + Package: fission.FunctionPackageRef{ PackageRef: fission.PackageRef{ - Name: p.Metadata.Name, - Namespace: p.Metadata.Namespace, + Namespace: p.Metadata.Namespace, + Name: p.Metadata.Name, + ResourceVersion: p.Metadata.ResourceVersion, }, }, - EnvironmentName: env.Metadata.Name, }, } _, err = fissionClient.Functions(fissionNs).Create(f) diff --git a/router/functionReferenceResolver.go b/router/functionReferenceResolver.go index b7c33cb3..feff53c9 100644 --- a/router/functionReferenceResolver.go +++ b/router/functionReferenceResolver.go @@ -29,14 +29,14 @@ import ( "github.com/fission/fission" "github.com/fission/fission/cache" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) type ( // functionReferenceResolver provides a resolver to turn a function // reference into a resolveResult functionReferenceResolver struct { - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient // FunctionReference -> function metadata refCache *cache.Cache @@ -68,7 +68,7 @@ const ( resolveResultSingleFunction = iota ) -func makeFunctionReferenceResolver(fissionClient *tpr.FissionClient) *functionReferenceResolver { +func makeFunctionReferenceResolver(fissionClient *crd.FissionClient) *functionReferenceResolver { frr := &functionReferenceResolver{ fissionClient: fissionClient, refCache: cache.MakeCache(time.Minute, 0), @@ -76,22 +76,22 @@ func makeFunctionReferenceResolver(fissionClient *tpr.FissionClient) *functionRe return frr } -// Sync starts syncing tpr function resources from k8s api server -func (frr *functionReferenceResolver) Sync(tprClient *rest.RESTClient) { +// Sync starts syncing crd function resources from k8s api server +func (frr *functionReferenceResolver) Sync(crdClient *rest.RESTClient) { stopCh := make(chan struct{}) - store, controller := makeK8SCache(tprClient) + store, controller := makeK8SCache(crdClient) frr.stopCh = stopCh frr.store = store go controller.Run(stopCh) } -// Stop stops tpr resources syncing +// Stop stops crd resources syncing func (frr *functionReferenceResolver) Stop() { frr.stopCh <- struct{}{} } -func makeK8SCache(tprClient *rest.RESTClient) (k8sCache.Store, k8sCache.Controller) { - watchlist := k8sCache.NewListWatchFromClient(tprClient, "functions", metav1.NamespaceDefault, fields.Everything()) +func makeK8SCache(crdClient *rest.RESTClient) (k8sCache.Store, k8sCache.Controller) { + watchlist := k8sCache.NewListWatchFromClient(crdClient, "functions", metav1.NamespaceDefault, fields.Everything()) listWatch := &k8sCache.ListWatch{ ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { return watchlist.List(options) @@ -101,7 +101,7 @@ func makeK8SCache(tprClient *rest.RESTClient) (k8sCache.Store, k8sCache.Controll }, } resyncPeriod := 30 * time.Second - return k8sCache.NewInformer(listWatch, &tpr.Function{}, resyncPeriod, + return k8sCache.NewInformer(listWatch, &crd.Function{}, resyncPeriod, k8sCache.ResourceEventHandlerFuncs{}) } @@ -145,7 +145,7 @@ func (frr *functionReferenceResolver) resolve(namespace string, fr *fission.Func // resolveByName simply looks up function by name in a namespace. func (frr *functionReferenceResolver) resolveByName(namespace, name string) (*resolveResult, error) { // get function from cache - obj, isExist, err := frr.store.Get(&tpr.Function{ + obj, isExist, err := frr.store.Get(&crd.Function{ Metadata: metav1.ObjectMeta{ Namespace: namespace, Name: name, @@ -158,7 +158,7 @@ func (frr *functionReferenceResolver) resolveByName(namespace, name string) (*re return nil, fmt.Errorf("function %v does not exist", name) } - f := obj.(*tpr.Function) + f := obj.(*crd.Function) rr := resolveResult{ resolveResultType: resolveResultSingleFunction, functionMetadata: &f.Metadata, diff --git a/router/httpTriggers.go b/router/httpTriggers.go index 8a3b805a..eb65fca3 100644 --- a/router/httpTriggers.go +++ b/router/httpTriggers.go @@ -30,31 +30,31 @@ import ( k8sCache "k8s.io/client-go/tools/cache" "github.com/fission/fission" + "github.com/fission/fission/crd" poolmgrClient "github.com/fission/fission/poolmgr/client" - "github.com/fission/fission/tpr" ) type HTTPTriggerSet struct { *functionServiceMap *mutableRouter - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient poolmgr *poolmgrClient.Client resolver *functionReferenceResolver - triggers []tpr.Httptrigger - functions []tpr.Function - tprClient *rest.RESTClient + triggers []crd.HTTPTrigger + functions []crd.Function + crdClient *rest.RESTClient } -func makeHTTPTriggerSet(fmap *functionServiceMap, fissionClient *tpr.FissionClient, - poolmgr *poolmgrClient.Client, resolver *functionReferenceResolver, tprClient *rest.RESTClient) *HTTPTriggerSet { - triggers := make([]tpr.Httptrigger, 1) +func makeHTTPTriggerSet(fmap *functionServiceMap, fissionClient *crd.FissionClient, + poolmgr *poolmgrClient.Client, resolver *functionReferenceResolver, crdClient *rest.RESTClient) *HTTPTriggerSet { + triggers := make([]crd.HTTPTrigger, 1) return &HTTPTriggerSet{ functionServiceMap: fmap, triggers: triggers, fissionClient: fissionClient, poolmgr: poolmgr, resolver: resolver, - tprClient: tprClient, + crdClient: crdClient, } } @@ -134,7 +134,7 @@ func (ts *HTTPTriggerSet) getRouter() *mux.Router { return muxRouter } -func (ts *HTTPTriggerSet) updateTriggerStatusFailed(ht *tpr.Httptrigger, err error) { +func (ts *HTTPTriggerSet) updateTriggerStatusFailed(ht *crd.HTTPTrigger, err error) { // TODO } @@ -142,7 +142,7 @@ func (ts *HTTPTriggerSet) watchTriggers() { // sync all http triggers ts.syncTriggers() - watchlist := k8sCache.NewListWatchFromClient(ts.tprClient, "httptriggers", metav1.NamespaceDefault, fields.Everything()) + watchlist := k8sCache.NewListWatchFromClient(ts.crdClient, "httptriggers", metav1.NamespaceDefault, fields.Everything()) listWatch := &k8sCache.ListWatch{ ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { return watchlist.List(options) @@ -152,7 +152,7 @@ func (ts *HTTPTriggerSet) watchTriggers() { }, } resyncPeriod := 30 * time.Second - _, controller := k8sCache.NewInformer(listWatch, &tpr.Httptrigger{}, resyncPeriod, + _, controller := k8sCache.NewInformer(listWatch, &crd.HTTPTrigger{}, resyncPeriod, k8sCache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { ts.syncTriggers() @@ -174,7 +174,7 @@ func (ts *HTTPTriggerSet) watchTriggers() { func (ts *HTTPTriggerSet) watchFunctions() { ts.syncTriggers() - watchlist := k8sCache.NewListWatchFromClient(ts.tprClient, "functions", metav1.NamespaceDefault, fields.Everything()) + watchlist := k8sCache.NewListWatchFromClient(ts.crdClient, "functions", metav1.NamespaceDefault, fields.Everything()) listWatch := &k8sCache.ListWatch{ ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { return watchlist.List(options) @@ -184,7 +184,7 @@ func (ts *HTTPTriggerSet) watchFunctions() { }, } resyncPeriod := 30 * time.Second - _, controller := k8sCache.NewInformer(listWatch, &tpr.Function{}, resyncPeriod, + _, controller := k8sCache.NewInformer(listWatch, &crd.Function{}, resyncPeriod, k8sCache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { ts.syncTriggers() @@ -193,7 +193,7 @@ func (ts *HTTPTriggerSet) watchFunctions() { ts.syncTriggers() }, UpdateFunc: func(oldObj interface{}, newObj interface{}) { - fn := newObj.(*tpr.Function) + fn := newObj.(*crd.Function) // update resolver function reference cache for key, rr := range ts.resolver.copy() { if key.functionReference.Name == fn.Metadata.Name && @@ -219,7 +219,7 @@ func (ts *HTTPTriggerSet) syncTriggers() { log.Printf("Syncing http triggers") // get triggers - triggers, err := ts.fissionClient.Httptriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) + triggers, err := ts.fissionClient.HTTPTriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) if err != nil { log.Fatalf("Failed to get http trigger list: %v", err) } diff --git a/router/router.go b/router/router.go index 2b133344..735ac42d 100644 --- a/router/router.go +++ b/router/router.go @@ -49,8 +49,8 @@ import ( "github.com/gorilla/handlers" "github.com/gorilla/mux" + "github.com/fission/fission/crd" poolmgrClient "github.com/fission/fission/poolmgr/client" - "github.com/fission/fission/tpr" ) // request url ---[mux]---> Function(name,uid) ----[fmap]----> k8s service url @@ -73,11 +73,11 @@ func serve(port int, httpTriggerSet *HTTPTriggerSet) { func Start(port int, poolmgrUrl string) { fmap := makeFunctionServiceMap(time.Minute) - fissionClient, _, err := tpr.MakeFissionClient() + fissionClient, _, _, err := crd.MakeFissionClient() if err != nil { log.Fatalf("Error connecting to kubernetes API: %v", err) } - restClient := fissionClient.GetTprClient() + restClient := fissionClient.GetCrdClient() poolmgr := poolmgrClient.MakeClient(poolmgrUrl) resolver := makeFunctionReferenceResolver(fissionClient) resolver.Sync(restClient) diff --git a/router/router_test.go b/router/router_test.go index b9fd2992..01e37b0f 100644 --- a/router/router_test.go +++ b/router/router_test.go @@ -24,7 +24,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/fission/fission" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) func TestRouter(t *testing.T) { @@ -61,7 +61,7 @@ func TestRouter(t *testing.T) { triggers := makeHTTPTriggerSet(fmap, nil, nil, frr, nil) triggerUrl := "/foo" triggers.triggers = append(triggers.triggers, - tpr.Httptrigger{ + crd.HTTPTrigger{ Metadata: metav1.ObjectMeta{ Name: "xxx", Namespace: metav1.NamespaceDefault, diff --git a/test/test_utils.sh b/test/test_utils.sh index e09d48d1..fc964adf 100755 --- a/test/test_utils.sh +++ b/test/test_utils.sh @@ -87,6 +87,13 @@ build_fission_cli() { popd } +clean_tpr_crd_resources() { + # clean tpr & crd resources to avoid testing error (ex. no kind "HttptriggerList" is registered for version "fission.io/v1") + # thirdpartyresources part should be removed after kubernetes test cluster is upgrade to 1.8+ + kubectl --namespace default get thirdpartyresources| grep -v NAME| grep "fission.io"| awk '{print $1}'|xargs -I@ bash -c "kubectl --namespace default delete thirdpartyresources @" || true + kubectl --namespace default get crd| grep -v NAME| grep "fission.io"| awk '{print $1}'|xargs -I@ bash -c "kubectl --namespace default delete crd @" || true +} + generate_test_id() { echo $(date|md5sum|cut -c1-6) } @@ -192,18 +199,18 @@ dump_fission_logs() { echo --- end $component logs --- } -dump_fission_tpr() { +dump_fission_crd() { type=$1 echo --- All objects of type $type --- kubectl --all-namespaces=true get $type -o yaml echo --- End objects of type $type --- } -dump_fission_tprs() { - dump_fission_tpr function.fission.io - dump_fission_tpr package.fission.io - dump_fission_tpr httptrigger.fission.io - dump_fission_tpr environment.fission.io +dump_fission_crds() { + dump_fission_crd function.fission.io + dump_fission_crd package.fission.io + dump_fission_crd httptrigger.fission.io + dump_fission_crd environment.fission.io } dump_env_pods() { @@ -234,7 +241,7 @@ dump_logs() { dump_fission_logs $ns $fns router dump_fission_logs $ns $fns poolmgr dump_function_pod_logs $ns $fns - dump_fission_tprs + dump_fission_crds } export FAILURES=0 @@ -267,6 +274,8 @@ install_and_test() { controllerPort=31234 routerPort=31235 + clean_tpr_crd_resources + id=$(generate_test_id) trap "helm_uninstall_fission $id" EXIT if ! helm_install_fission $id $image $imageTag $fetcherImage $fetcherImageTag $controllerPort $routerPort diff --git a/timer/main.go b/timer/main.go index 301464d2..6234efb5 100644 --- a/timer/main.go +++ b/timer/main.go @@ -17,12 +17,12 @@ limitations under the License. package timer import ( + "github.com/fission/fission/crd" "github.com/fission/fission/publisher" - "github.com/fission/fission/tpr" ) func Start(routerUrl string) error { - fissionClient, _, err := tpr.MakeFissionClient() + fissionClient, _, _, err := crd.MakeFissionClient() if err != nil { return err } diff --git a/timer/timer.go b/timer/timer.go index 4ef09848..d6620a61 100644 --- a/timer/timer.go +++ b/timer/timer.go @@ -22,8 +22,8 @@ import ( "github.com/robfig/cron" "github.com/fission/fission" + "github.com/fission/fission/crd" "github.com/fission/fission/publisher" - "github.com/fission/fission/tpr" ) type requestType int @@ -41,14 +41,14 @@ type ( timerRequest struct { requestType - triggers []tpr.Timetrigger + triggers []crd.TimeTrigger responseChannel chan *timerResponse } timerResponse struct { error } timerTriggerWithCron struct { - trigger tpr.Timetrigger + trigger crd.TimeTrigger cron *cron.Cron } ) @@ -63,7 +63,7 @@ func MakeTimer(publisher publisher.Publisher) *Timer { return timer } -func (timer *Timer) Sync(triggers []tpr.Timetrigger) error { +func (timer *Timer) Sync(triggers []crd.TimeTrigger) error { req := &timerRequest{ requestType: SYNC, triggers: triggers, @@ -85,7 +85,7 @@ func (timer *Timer) svc() { } } -func (timer *Timer) syncCron(triggers []tpr.Timetrigger) error { +func (timer *Timer) syncCron(triggers []crd.TimeTrigger) error { // add new triggers or update existing ones for _, t := range triggers { if item, ok := timer.triggers[t.Metadata.Name]; ok { @@ -137,7 +137,7 @@ func (timer *Timer) syncCron(triggers []tpr.Timetrigger) error { return nil } -func (timer *Timer) newCron(t tpr.Timetrigger) *cron.Cron { +func (timer *Timer) newCron(t crd.TimeTrigger) *cron.Cron { c := cron.New() c.AddFunc(t.Spec.Cron, func() { headers := map[string]string{ diff --git a/timer/timerSync.go b/timer/timerSync.go index 6567d80d..4509be08 100644 --- a/timer/timerSync.go +++ b/timer/timerSync.go @@ -22,17 +22,17 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/fission/fission/tpr" + "github.com/fission/fission/crd" ) type ( TimerSync struct { - fissionClient *tpr.FissionClient + fissionClient *crd.FissionClient timer *Timer } ) -func MakeTimerSync(fissionClient *tpr.FissionClient, timer *Timer) *TimerSync { +func MakeTimerSync(fissionClient *crd.FissionClient, timer *Timer) *TimerSync { ws := &TimerSync{ fissionClient: fissionClient, timer: timer, @@ -43,7 +43,7 @@ func MakeTimerSync(fissionClient *tpr.FissionClient, timer *Timer) *TimerSync { func (ws *TimerSync) syncSvc() { for { - triggers, err := ws.fissionClient.Timetriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) + triggers, err := ws.fissionClient.TimeTriggers(metav1.NamespaceAll).List(metav1.ListOptions{}) if err != nil { log.Fatalf("Failed get time trigger list: %v", err) } diff --git a/tpr/tpr.go b/tpr/tpr.go deleted file mode 100644 index 4f542108..00000000 --- a/tpr/tpr.go +++ /dev/null @@ -1,115 +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 tpr - -import ( - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/pkg/apis/extensions/v1beta1" -) - -// ensureTPR checks if the given TPR type exists, and creates it if -// needed. (Note that this creates the TPR type; it doesn't create any -// _instances_ of that type.) -func ensureTPR(clientset *kubernetes.Clientset, tpr *v1beta1.ThirdPartyResource) error { - _, err := clientset.Extensions().ThirdPartyResources().Get(tpr.ObjectMeta.Name, metav1.GetOptions{}) - if err != nil { - if errors.IsNotFound(err) { - _, err := clientset.Extensions().ThirdPartyResources().Create(tpr) - if err != nil { - return err - } - } - } - return nil -} - -func EnsureFissionTPRs(clientset *kubernetes.Clientset) error { - tprs := []v1beta1.ThirdPartyResource{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "function.fission.io", - }, - Versions: []v1beta1.APIVersion{ - {Name: "v1"}, - }, - Description: "Functions", - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "environment.fission.io", - }, - Versions: []v1beta1.APIVersion{ - {Name: "v1"}, - }, - Description: "Environments (function containers)", - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "httptrigger.fission.io", - }, - Versions: []v1beta1.APIVersion{ - {Name: "v1"}, - }, - Description: "HTTP triggers for functions", - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "kuberneteswatchtrigger.fission.io", - }, - Versions: []v1beta1.APIVersion{ - {Name: "v1"}, - }, - Description: "Kubernetes watch triggers for functions", - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "timetrigger.fission.io", - }, - Versions: []v1beta1.APIVersion{ - {Name: "v1"}, - }, - Description: "Time-based triggers for functions", - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "messagequeuetrigger.fission.io", - }, - Versions: []v1beta1.APIVersion{ - {Name: "v1"}, - }, - Description: "Message queue triggers for functions", - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "package.fission.io", - }, - Versions: []v1beta1.APIVersion{ - {Name: "v1"}, - }, - Description: "Packages: archives containing source or binaries for one or more functions", - }, - } - for _, tpr := range tprs { - err := ensureTPR(clientset, &tpr) - if err != nil { - return err - } - } - return nil -}