You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@submarine.apache.org by li...@apache.org on 2019/12/15 14:04:16 UTC
[submarine] branch master updated: SUBMARINE-316. Support listen
k8s event in submarine operator
This is an automated email from the ASF dual-hosted git repository.
liuxun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/submarine.git
The following commit(s) were added to refs/heads/master by this push:
new 07ef255 SUBMARINE-316. Support listen k8s event in submarine operator
07ef255 is described below
commit 07ef2558752a6cb12eebb28c3fb49a5298b65ec5
Author: Xun Liu <li...@apache.org>
AuthorDate: Sat Dec 14 17:03:59 2019 +0800
SUBMARINE-316. Support listen k8s event in submarine operator
### What is this PR for?
Listen to k8s pod, svc creation, destruction and other events in the submarine operator.
* [x] - Submarine CRD auto register
* [x] - Submarine Cluster SVC add/remove event listen
* [x] - Submarine Cluster POD add/remove event listen
#### How To Test
```
cd submarine-cloud
make
./submarine-operator --kubeconfig=$KUBECONFIG --alsologtostderr
```
open new console
```
kubectl apply test1.yaml
kubectl apply test2.yaml
kubectl delete test2.yaml
kubectl delete test2.yaml
```
### What type of PR is it?
Feature
### What is the Jira issue?
* https://issues.apache.org/jira/browse/SUBMARINE-316
### How should this be tested?
* [CI Pass](https://travis-ci.org/liuxunorg/submarine/builds/624659081)
### Screenshots (if appropriate)
### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No
Author: Xun Liu <li...@apache.org>
Closes #129 from liuxunorg/SUBMARINE-316 and squashes the following commits:
dc3fd11 [Xun Liu] Fixed function & var name
a95cb8f [Xun Liu] Fixed licenses head.
073f05f [Xun Liu] SUBMARINE-316. Support k8s event listen in submarine operator
---
submarine-cloud/Makefile | 4 +-
submarine-cloud/cmd/operator/controller.go | 253 --------------------
submarine-cloud/cmd/operator/main.go | 158 ++-----------
submarine-cloud/go.mod | 6 +-
submarine-cloud/go.sum | 108 +++++++++
submarine-cloud/hack/update-codegen.sh | 4 -
submarine-cloud/manifests/test1.yaml | 2 +-
submarine-cloud/manifests/test2.yaml | 2 +-
.../pkg/apis/submarine/v1alpha1/default.go | 66 ++++++
submarine-cloud/pkg/apis/submarine/v1alpha1/doc.go | 1 -
.../pkg/apis/submarine/v1alpha1/register.go | 17 +-
.../pkg/apis/submarine/v1alpha1/types.go | 195 +++++++++++++++-
.../submarine/v1alpha1/zz_generated.deepcopy.go | 151 ++++++++++--
submarine-cloud/pkg/client/client.go | 114 +++++++++
.../v1alpha1/fake/fake_submarine_client.go | 4 +-
.../v1alpha1/fake/fake_submarinecluster.go | 141 +++++++++++
.../v1alpha1/fake/fake_submarineserver.go | 129 -----------
.../submarine/v1alpha1/generated_expansion.go | 2 +-
.../typed/submarine/v1alpha1/submarine_client.go | 6 +-
.../typed/submarine/v1alpha1/submarinecluster.go | 192 +++++++++++++++
.../typed/submarine/v1alpha1/submarineserver.go | 175 --------------
.../client/informers/externalversions/generic.go | 4 +-
.../submarine/v1alpha1/interface.go | 10 +-
.../{submarineserver.go => submarinecluster.go} | 38 +--
.../submarine/v1alpha1/expansion_generated.go | 12 +-
.../listers/submarine/v1alpha1/submarinecluster.go | 95 ++++++++
.../listers/submarine/v1alpha1/submarineserver.go | 95 --------
.../{signals/signal_posix.go => config/cluster.go} | 20 +-
submarine-cloud/pkg/config/submarine.go | 101 ++++++++
.../signal_windows.go => controller/config.go} | 19 +-
submarine-cloud/pkg/controller/controller.go | 258 +++++++++++++++++++++
submarine-cloud/pkg/controller/pod/control.go | 88 +++++++
.../pkg/controller/poddisruptionbudgets_control.go | 66 ++++++
submarine-cloud/pkg/controller/services_control.go | 70 ++++++
submarine-cloud/pkg/operator/config.go | 43 ++++
submarine-cloud/pkg/operator/operator.go | 95 ++++++++
submarine-cloud/pkg/{signals => signal}/signal.go | 34 ++-
submarine-cloud/pkg/utils/build.go | 47 ++++
submarine-cloud/submarine-operator.md | 1 +
39 files changed, 1932 insertions(+), 894 deletions(-)
diff --git a/submarine-cloud/Makefile b/submarine-cloud/Makefile
index c4ea405..830c7b7 100644
--- a/submarine-cloud/Makefile
+++ b/submarine-cloud/Makefile
@@ -31,7 +31,7 @@ LDFLAGS := -s -w \
.PHONY: build
build:
- $(GOBUILD) -o ./$(BINARY_NAME) -v cmd/operator/main.go cmd/operator/controller.go
+ $(GOBUILD) -o ./$(BINARY_NAME) -v cmd/operator/main.go
test:
$(GOTEST) -v ./...
@@ -47,4 +47,4 @@ fmt:
@go fmt $(CURDIR)/...
release:
- CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -a -installsuffix cgo -ldflags "$(LDFLAGS)" -o ./$(BINARY_UNIX)-linux-amd64-$(VERSION) -v cmd/operator/main.go cmd/operator/controller.go
+ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -a -installsuffix cgo -ldflags "$(LDFLAGS)" -o ./$(BINARY_UNIX)-linux-amd64-$(VERSION) -v cmd/operator/main.go
diff --git a/submarine-cloud/cmd/operator/controller.go b/submarine-cloud/cmd/operator/controller.go
deleted file mode 100644
index 576b352..0000000
--- a/submarine-cloud/cmd/operator/controller.go
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 (
- "fmt"
- "time"
-
- "github.com/golang/glog"
- corev1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/errors"
- "k8s.io/apimachinery/pkg/util/runtime"
- utilruntime "k8s.io/apimachinery/pkg/util/runtime"
- "k8s.io/apimachinery/pkg/util/wait"
- "k8s.io/client-go/kubernetes"
- "k8s.io/client-go/kubernetes/scheme"
- typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
- "k8s.io/client-go/tools/cache"
- "k8s.io/client-go/tools/record"
- "k8s.io/client-go/util/workqueue"
-
- stablev1 "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
- clientset "github.com/apache/submarine/submarine-cloud/pkg/client/clientset/versioned"
- studentscheme "github.com/apache/submarine/submarine-cloud/pkg/client/clientset/versioned/scheme"
- informers "github.com/apache/submarine/submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1"
- listers "github.com/apache/submarine/submarine-cloud/pkg/client/listers/submarine/v1alpha1"
-)
-
-const controllerName = "submarine-controller"
-
-const (
- SuccessSynced = "Synced"
- MessageResourceSynced = "SubmarineServer Object synced successfully"
- MessageTest = "Someone changed the email in a distributed system," + controllerName + "automatically completed the evolution to the end state"
-)
-
-// Controller is the controller implementation for Student resources
-type SubmarineController struct {
- // k8s's clientset
- kubeclientset kubernetes.Interface
- // our own API group的clientset
- submarineServerClientset clientset.Interface
-
- submarineServerLister listers.SubmarineServerLister
- submarineServerSynced cache.InformerSynced
-
- workQueue workqueue.RateLimitingInterface
-
- syncHandler func(dKey string) error
-
- recorder record.EventRecorder
-}
-
-// New SubmarineController
-func NewSubmarineController(
- kubeclientset kubernetes.Interface,
- studentclientset clientset.Interface,
- studentInformer informers.SubmarineServerInformer) *SubmarineController {
-
- utilruntime.Must(studentscheme.AddToScheme(scheme.Scheme))
- glog.Info("Create event broadcaster")
- eventBroadcaster := record.NewBroadcaster()
- eventBroadcaster.StartLogging(glog.Infof)
- eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeclientset.CoreV1().Events("")})
-
- // FIXME Create a source is the controllerAgentName event logger, which is itself part of the audit / log
- // kubectl describe crd test1
- recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerName})
- controller := &SubmarineController{
- kubeclientset: kubeclientset,
- submarineServerClientset: studentclientset,
- submarineServerLister: studentInformer.Lister(),
- submarineServerSynced: studentInformer.Informer().HasSynced,
- workQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Students"),
- recorder: recorder,
- }
-
- glog.Info("Listen for SubmarineServer's add / update / delete events")
-
- studentInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
- AddFunc: controller.addSubmarineServerHandler,
- UpdateFunc: func(old, new interface{}) {
- oldSubmarineServer := old.(*stablev1.SubmarineServer)
- newSubmarineServer := new.(*stablev1.SubmarineServer)
- // The versions are the same, which means that there is no actual update operation
- if oldSubmarineServer.ResourceVersion == newSubmarineServer.ResourceVersion {
- return
- }
- controller.addSubmarineServerHandler(new)
- },
- DeleteFunc: controller.deleteSubmarineServerHandler,
- })
-
- controller.syncHandler = controller.syncSubmarineServer
-
- return controller
-}
-
-// Start your controller business here
-func (c *SubmarineController) Run(max int, stopCh <-chan struct{}) error {
- defer runtime.HandleCrash()
- defer c.workQueue.ShutDown()
-
- glog.Info("Start the controller event and start a cache data synchronization")
- if ok := cache.WaitForCacheSync(stopCh, c.submarineServerSynced); !ok {
- return fmt.Errorf("failed to wait for caches to sync")
- }
-
- glog.Infof("Start %d worker", max)
- for i := 0; i < max; i++ {
- go wait.Until(c.runWorker, time.Second, stopCh)
- }
-
- glog.Info("worker all started")
-
- <-stopCh
-
- glog.Info("worker all stop")
- glog.Infof("%s final.", controllerName)
-
- return nil
-}
-
-func (c *SubmarineController) runWorker() {
- for c.processNextWorkItem() {
- }
-}
-
-// worker Fetching data
-func (c *SubmarineController) processNextWorkItem() bool {
- // Get a student from the queue
- obj, shutdown := c.workQueue.Get()
- if shutdown {
- return false
- }
-
- err := func(obj interface{}) error {
- defer c.workQueue.Done(obj)
- var key string
- var ok bool
-
- if key, ok = obj.(string); !ok {
- c.workQueue.Forget(obj)
- runtime.HandleError(fmt.Errorf("expected string in workQueue but got %#v", obj))
- return nil
- }
- // Handling event in syncHandler
- if err := c.syncSubmarineServer(key); err != nil {
- return fmt.Errorf("error syncing '%s': %s", key, err.Error())
- }
-
- c.workQueue.Forget(obj)
- glog.Infof("Successfully synced '%s'", key)
- return nil
- }(obj)
-
- if err != nil {
- runtime.HandleError(err)
- return true
- }
-
- return true
-}
-
-// Specific process
-func (c *SubmarineController) syncSubmarineServer(key string) error {
- namespace, name, err := cache.SplitMetaNamespaceKey(key)
- if err != nil {
- runtime.HandleError(fmt.Errorf("invalid resource key: %s", key))
- return nil
- }
-
- // Fetching objects from the cache
- submarineServer, err := c.submarineServerLister.SubmarineServers(namespace).Get(name)
- if err != nil {
- // If the Student object is deleted, it will come here, so you should add execution here
- if errors.IsNotFound(err) {
- glog.Infof("SubmarineServer object is deleted, please perform the actual deletion event here: %s/%s ...", namespace, name)
-
- return nil
- }
-
- runtime.HandleError(fmt.Errorf("failed to list SubmarineServer by: %s/%s", namespace, name))
-
- return err
- }
-
- glog.Infof("Here is the actual state of the SubmarineServer object: %v ...", submarineServer)
- submarineServerCopy := submarineServer.DeepCopy()
-
- // FIXME Here is the simulated end-state business
- if submarineServerCopy.Spec.Name == "gfandada" && submarineServerCopy.Spec.Email != "gfandada@gmail.com" {
- glog.Infof("===========================================================================================================")
- submarineServerCopy.Spec.Email = "gfandada@gmail.com"
- glog.Infof("Expected state%v", submarineServerCopy)
- glog.Infof("name=%v resourceVersion=%v ns=%v 类型=%v owner=%v uid=%v", submarineServerCopy.Name, submarineServerCopy.ResourceVersion,
- submarineServerCopy.Namespace, submarineServerCopy.Kind, submarineServerCopy.OwnerReferences, submarineServerCopy.UID)
-
- // FIXME crd's curd generally needs to be encapsulated, you can refer to the encapsulation of Deployment
- result := &stablev1.SubmarineServer{}
- c.submarineServerClientset.SubmarineV1alpha1().RESTClient().Put().
- Namespace(submarineServerCopy.Namespace).
- Resource("submarineservers").Name(submarineServerCopy.Name).Body(submarineServerCopy).Do().Into(result)
- c.recorder.Event(submarineServer, corev1.EventTypeWarning, SuccessSynced, MessageTest)
- glog.Infof("===========================================================================================================")
- return nil
- }
- c.recorder.Event(submarineServer, corev1.EventTypeNormal, SuccessSynced, MessageResourceSynced)
- return nil
-}
-
-// Add SubmarineServer
-func (c *SubmarineController) addSubmarineServerHandler(obj interface{}) {
- var key string
- var err error
-
- // Put objects in cache
- if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
- runtime.HandleError(err)
- return
- }
- // Put the key into the queue
- c.workQueue.AddRateLimited(key)
-}
-
-// Delete SubmarineServer
-func (c *SubmarineController) deleteSubmarineServerHandler(obj interface{}) {
- var key string
- var err error
-
- // Removes the specified object from the cache
- key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
- if err != nil {
- runtime.HandleError(err)
- return
- }
- // Put the key into the queue
- c.workQueue.AddRateLimited(key)
-}
diff --git a/submarine-cloud/cmd/operator/main.go b/submarine-cloud/cmd/operator/main.go
index 3c94fc6..aafcc9a 100644
--- a/submarine-cloud/cmd/operator/main.go
+++ b/submarine-cloud/cmd/operator/main.go
@@ -18,154 +18,46 @@
package main
import (
+ "context"
+ goflag "flag"
"fmt"
- clientset "github.com/apache/submarine/submarine-cloud/pkg/client/clientset/versioned"
- informers "github.com/apache/submarine/submarine-cloud/pkg/client/informers/externalversions"
- "github.com/apache/submarine/submarine-cloud/pkg/signals"
+ "github.com/apache/submarine/submarine-cloud/pkg/operator"
+ "github.com/apache/submarine/submarine-cloud/pkg/signal"
+ "github.com/apache/submarine/submarine-cloud/pkg/utils"
"github.com/golang/glog"
- "github.com/mitchellh/go-homedir"
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
- "k8s.io/client-go/kubernetes"
- "k8s.io/client-go/tools/clientcmd"
+ "github.com/spf13/pflag"
"os"
- "strings"
- "time"
+ "runtime"
)
-// rootCmd represents the base command when called without any subcommands
-var rootCmd = &cobra.Command{
- Use: "submarineController",
- Short: "Apache submarine operator",
- Long: "Apache submarine operator",
- // Uncomment the following line if your bare application
- // has an action associated with it:
- // Run: func(cmd *cobra.Command, args []string) { },
-}
-
-var cfgFile string
-
-func init() {
- cobra.OnInitialize(initConfig)
-
- // Here you will define your flags and configuration settings.
- // Cobra supports persistent flags, which, if defined here,
- // will be global for your application.
- rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.samplecontroller.yaml)")
-
- // Cobra also supports local flags, which will only run
- // when this action is called directly.
- rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
-
- rootCmd.AddCommand(runCmd)
- // Here you will define your flags and configuration settings.
-
- // Cobra supports Persistent Flags which will work for this command
- // and all subcommands, e.g.:
- // runCmd.PersistentFlags().String("foo", "", "A help for foo")
-
- // Cobra supports local flags which will only run when this command
- // is called directly, e.g.:
- // runCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
-}
-
func main() {
- if err := rootCmd.Execute(); err != nil {
- fmt.Println(err)
- os.Exit(1)
- }
-}
-
-// runCmd represents the run command
-var runCmd = &cobra.Command{
- Use: "run",
- Short: "run config=[kubeConfig's path]",
- Long: ``,
- Run: func(cmd *cobra.Command, args []string) {
- NewApp(args)
- },
-}
+ utils.BuildInfos()
+ runtime.GOMAXPROCS(runtime.NumCPU())
-// initConfig reads in config file and ENV variables if set.
-func initConfig() {
- if cfgFile != "" {
- // Use config file from the flag.
- viper.SetConfigFile(cfgFile)
- } else {
- // Find home directory.
- home, err := homedir.Dir()
- if err != nil {
- fmt.Println(err)
- os.Exit(1)
- }
+ config := operator.NewSubmarineOperatorConfig()
+ config.AddFlags(pflag.CommandLine)
- // Search config in home directory with name ".samplecontroller" (without extension).
- viper.AddConfigPath(home)
- viper.SetConfigName(".submarineController")
- }
+ pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
+ pflag.Parse()
+ goflag.CommandLine.Parse([]string{})
- viper.AutomaticEnv() // read in environment variables that match
+ fmt.Println("config:", config)
- // If a config file is found, read it in.
- if err := viper.ReadInConfig(); err == nil {
- fmt.Println("Using config file:", viper.ConfigFileUsed())
- }
-}
+ op := operator.NewSubmarineOperator(config)
-func getKubeCfg(args []string) string {
- for _, v := range args {
- strs := strings.Split(v, "=")
- if strs[0] == "config" {
- return strs[1]
- }
+ if err := run(op); err != nil {
+ glog.Errorf("SubmarineOperator returns an error:%v", err)
+ os.Exit(1)
}
- return ""
-}
-func getKubeMasterUrl(args []string) string {
- for _, v := range args {
- strs := strings.Split(v, "=")
- if strs[0] == "master" {
- return strs[1]
- }
- }
- return ""
+ os.Exit(0)
}
-func NewApp(args []string) {
- defer glog.Flush()
- // Processing semaphores
- stopCh := signals.SetupSignalHandler()
+func run(op *operator.SubmarineOperator) error {
+ ctx, cancelFunc := context.WithCancel(context.Background())
+ go signal.HandleSignal(cancelFunc)
- // Processing input parameters
- cfg, err := clientcmd.BuildConfigFromFlags(getKubeMasterUrl(args), getKubeCfg(args))
- if err != nil {
- glog.Fatalf("Error building kubeconfig: %s", err.Error())
- }
+ op.Run(ctx.Done())
- // Create a standard client
- kubeClient, err := kubernetes.NewForConfig(cfg)
- if err != nil {
- glog.Fatalf("Error building kubernetes clientset: %s", err.Error())
- }
-
- // Create a client for student resources
- studentClient, err := clientset.NewForConfig(cfg)
- if err != nil {
- glog.Fatalf("Error building example clientset: %s", err.Error())
- }
-
- // Create informer
- studentInformerFactory := informers.NewSharedInformerFactory(studentClient, time.Second*30)
-
- controller := NewSubmarineController(kubeClient, studentClient,
- studentInformerFactory.Submarine().V1alpha1().SubmarineServers())
-
- // Start informer
- go studentInformerFactory.Start(stopCh)
-
- // Start controller
- if err = controller.Run(10, stopCh); err != nil {
- glog.Fatalf("Error running controller: %s", err.Error())
- }
+ return nil
}
diff --git a/submarine-cloud/go.mod b/submarine-cloud/go.mod
index bf749d7..f85ba40 100644
--- a/submarine-cloud/go.mod
+++ b/submarine-cloud/go.mod
@@ -8,10 +8,12 @@ require (
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/mitchellh/go-homedir v1.1.0
github.com/spf13/cobra v0.0.5
+ github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.5.0
k8s.io/api v0.0.0-20191121015604-11707872ac1c
- k8s.io/apimachinery v0.0.0-20191121015412-41065c7a8c2a
- k8s.io/client-go v0.0.0-20191121015835-571c0ef67034
+ k8s.io/apiextensions-apiserver v0.0.0-20191204090421-cd61debedab5
+ k8s.io/apimachinery v0.0.0-20191203211716-adc6f4cd9e7d
+ k8s.io/client-go v0.0.0-20191204082520-bc9b51d240b2
k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e
)
diff --git a/submarine-cloud/go.sum b/submarine-cloud/go.sum
index 9882011..ce4a608 100644
--- a/submarine-cloud/go.sum
+++ b/submarine-cloud/go.sum
@@ -1,6 +1,7 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
@@ -13,62 +14,117 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/apache/submarine v0.0.0-20191203011414-d394781a2c7d h1:jX4hWmypNtuNhMONSBeT+UvxhOSNSr4hq9PgGLwFI20=
+github.com/apache/submarine v0.0.0-20191210121440-855c010715db h1:ZLSnW9MFe1alw+vfwrGx6n326f9Yj/zpwLPTRp5x1CA=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
+github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
+github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I=
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
+github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
+github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
+github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
+github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
+github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
+github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
+github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
+github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
+github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
+github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
+github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
+github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
+github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
+github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
+github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
+github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
+github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
+github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
+github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
+github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
+github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
+github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
+github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
+github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
+github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
+github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
+github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
+github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
+github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
+github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
+github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@@ -97,16 +153,20 @@ github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
+github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -119,6 +179,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
@@ -136,10 +198,15 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -153,33 +220,43 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
@@ -187,11 +264,13 @@ github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@@ -207,13 +286,23 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
+go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
@@ -221,7 +310,9 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -237,15 +328,18 @@ golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -265,6 +359,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -283,31 +378,43 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.0.0-20191121015604-11707872ac1c h1:Z87my3sF4WhG0OMxzARkWY/IKBtOr+MhXZAb4ts6qFc=
k8s.io/api v0.0.0-20191121015604-11707872ac1c/go.mod h1:R/s4gKT0V/cWEnbQa9taNRJNbWUK57/Dx6cPj6MD3A0=
+k8s.io/apiextensions-apiserver v0.0.0-20191204090421-cd61debedab5 h1:g+GvnbGqLU1Jxb/9iFm/BFcmkqG9HdsGh52+wHirpsM=
+k8s.io/apiextensions-apiserver v0.0.0-20191204090421-cd61debedab5/go.mod h1:CPw0IHz1YrWGy0+8mG/76oTHXvChlgCb3EAezKQKB2I=
k8s.io/apimachinery v0.0.0-20191121015412-41065c7a8c2a h1:9V03T5lHv/iF4fSgvMCd+iB86AgEgmzLpheMqIJy7hs=
k8s.io/apimachinery v0.0.0-20191121015412-41065c7a8c2a/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
+k8s.io/apiserver v0.0.0-20191204084332-137a9d3b886b/go.mod h1:itgfam5HJbT/4b2BGfpUkkxfheMmDH+Ix+tEAP3uqZk=
k8s.io/client-go v0.0.0-20191121015835-571c0ef67034 h1:+/ppGIi1rJThJAz/xJSSOuD82gb6E5jRv2305MSznxQ=
k8s.io/client-go v0.0.0-20191121015835-571c0ef67034/go.mod h1:Adhj+OyDRsEXTnL9BfL7xbLWGWMCqGLWpMqGHkZI4J8=
k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e h1:HB9Zu5ZUvJfNpLiTPhz+CebVKV8C39qTBMQkAgAZLNw=
k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
+k8s.io/component-base v0.0.0-20191204083903-0d4d24e738e4/go.mod h1:8VIh1jErItC4bg9hLBkPneyS77Tin8KwSzbYepHJnQI=
+k8s.io/component-base v0.0.0-20191204083906-3ac1376c73aa/go.mod h1:mECWvHCPhJudDVDMtBl+AIf/YnTMp5r1F947OYFUwP0=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20190822140433-26a664648505 h1:ZY6yclUKVbZ+SdWnkfY+Je5vrMpKOxmGeKRbsXVmqYM=
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
@@ -325,5 +432,6 @@ modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
+sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
diff --git a/submarine-cloud/hack/update-codegen.sh b/submarine-cloud/hack/update-codegen.sh
index e6aaf49..e16484f 100755
--- a/submarine-cloud/hack/update-codegen.sh
+++ b/submarine-cloud/hack/update-codegen.sh
@@ -24,10 +24,6 @@ set -o pipefail
SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo $GOPATH/src/k8s.io/code-generator/)}
-#cp -R "$(dirname "${BASH_SOURCE[0]}")/../github.com/apache/submarine/submarine-cloud/pkg" "$(dirname "${BASH_SOURCE[0]}")/.."
-
-#exit;
-
# generate the code with:
# --output-base because this script should also be able to run inside the vendor dir of
# k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir
diff --git a/submarine-cloud/manifests/test1.yaml b/submarine-cloud/manifests/test1.yaml
index f242e06..ab1cbbf 100644
--- a/submarine-cloud/manifests/test1.yaml
+++ b/submarine-cloud/manifests/test1.yaml
@@ -15,7 +15,7 @@
# limitations under the License.
#
apiVersion: submarine.apache.org/v1alpha1
-kind: SubmarineServer
+kind: SubmarineCluster
metadata:
name: test1
spec:
diff --git a/submarine-cloud/manifests/test2.yaml b/submarine-cloud/manifests/test2.yaml
index 2c6fc27..e05a637 100644
--- a/submarine-cloud/manifests/test2.yaml
+++ b/submarine-cloud/manifests/test2.yaml
@@ -15,7 +15,7 @@
# limitations under the License.
#
apiVersion: submarine.apache.org/v1alpha1
-kind: SubmarineServer
+kind: SubmarineCluster
metadata:
name: test2
spec:
diff --git a/submarine-cloud/pkg/apis/submarine/v1alpha1/default.go b/submarine-cloud/pkg/apis/submarine/v1alpha1/default.go
new file mode 100644
index 0000000..15ab53f
--- /dev/null
+++ b/submarine-cloud/pkg/apis/submarine/v1alpha1/default.go
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 v1alpha1
+
+import (
+ "github.com/golang/glog"
+ kapiv1 "k8s.io/api/core/v1"
+)
+
+// IsDefaultedSubmarineCluster check if the SubmarineCluster is already defaulted
+func IsDefaultedSubmarineCluster(rc *SubmarineCluster) bool {
+ if rc.Spec.NumberOfMaster == nil {
+ return false
+ }
+ if rc.Spec.ReplicationFactor == nil {
+ return false
+ }
+ return true
+}
+
+// DefaultSubmarineCluster defaults SubmarineCluster
+func DefaultSubmarineCluster(undefaultSubmarineCluster *SubmarineCluster) *SubmarineCluster {
+ glog.Infof("DefaultSubmarineCluster()")
+ rc := undefaultSubmarineCluster.DeepCopy()
+ if rc.Spec.NumberOfMaster == nil {
+ rc.Spec.NumberOfMaster = NewInt32(3)
+ }
+ if rc.Spec.ReplicationFactor == nil {
+ rc.Spec.ReplicationFactor = NewInt32(1)
+ }
+
+ if rc.Spec.PodTemplate == nil {
+ rc.Spec.PodTemplate = &kapiv1.PodTemplateSpec{}
+ }
+
+ rc.Status.Cluster.NumberOfMaster = 0
+ rc.Status.Cluster.MinReplicationFactor = 0
+ rc.Status.Cluster.MaxReplicationFactor = 0
+ rc.Status.Cluster.NbPods = 0
+ rc.Status.Cluster.NbPodsReady = 0
+ rc.Status.Cluster.NbSubmarineRunning = 0
+
+ return rc
+}
+
+// NewInt32 use to instanciate a int32 pointer
+func NewInt32(val int32) *int32 {
+ output := new(int32)
+ *output = val
+
+ return output
+}
diff --git a/submarine-cloud/pkg/apis/submarine/v1alpha1/doc.go b/submarine-cloud/pkg/apis/submarine/v1alpha1/doc.go
index 731dd9a..d848b4c 100644
--- a/submarine-cloud/pkg/apis/submarine/v1alpha1/doc.go
+++ b/submarine-cloud/pkg/apis/submarine/v1alpha1/doc.go
@@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
// +k8s:deepcopy-gen=package
// +groupName=submarine.apache.org
diff --git a/submarine-cloud/pkg/apis/submarine/v1alpha1/register.go b/submarine-cloud/pkg/apis/submarine/v1alpha1/register.go
index b55355e..cbff1d9 100644
--- a/submarine-cloud/pkg/apis/submarine/v1alpha1/register.go
+++ b/submarine-cloud/pkg/apis/submarine/v1alpha1/register.go
@@ -15,7 +15,7 @@
* limitations under the License.
*/
// The purpose of this file is to make the client know the
-// Student type API object through the addKnownTypes method:
+// Submarine type API object through the addKnownTypes method:
package v1alpha1
import (
@@ -46,11 +46,22 @@ func Kind(kind string) schema.GroupKind {
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(
SchemeGroupVersion,
- &SubmarineServer{},
- &SubmarineServerList{},
+ &SubmarineCluster{},
+ &SubmarineClusterList{},
)
// register the type in the scheme
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}
+
+const (
+ // ResourcePlural is the id to indentify pluarals
+ ResourcePlural = "submarineclusters"
+ // ResourceSingular represents the id for identify singular resource
+ ResourceSingular = "submarinecluster"
+ // ResourceKind represent the resource kind
+ ResourceKind = "SubmarineCluster"
+ // ResourceVersion represent the resource version
+ ResourceVersion = "v1alpha1"
+)
diff --git a/submarine-cloud/pkg/apis/submarine/v1alpha1/types.go b/submarine-cloud/pkg/apis/submarine/v1alpha1/types.go
index aa9d3e1..68e32c8 100644
--- a/submarine-cloud/pkg/apis/submarine/v1alpha1/types.go
+++ b/submarine-cloud/pkg/apis/submarine/v1alpha1/types.go
@@ -14,36 +14,209 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package v1alpha1
import (
+ "fmt"
+ kapiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
-// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-type SubmarineServer struct {
+// SubmarineCluster represents a Submarine Cluster
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+type SubmarineCluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
- Spec SubmarineServerSpec `json:"spec"`
+
+ // Spec represents the desired SubmarineCluster specification
+ Spec SubmarineClusterSpec `json:"spec,omitempty"`
+
+ // Status represents the current SubmarineCluster status
+ Status SubmarineClusterStatus `json:"status,omitempty"`
}
-type SubmarineServerSpec struct {
+// SubmarineClusterList is a list of Submarine resources
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+type SubmarineClusterList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata"`
+
+ Items []SubmarineCluster `json:"items"`
+}
+
+// SubmarineClusterSpec contains SubmarineCluster specification
+type SubmarineClusterSpec struct {
+ NumberOfMaster *int32 `json:"numberOfMaster,omitempty"`
+ ReplicationFactor *int32 `json:"replicationFactor,omitempty"`
+
+ // ServiceName name used to create the Kubernetes Service that reference the Submarine Cluster nodes.
+ // if ServiceName is empty, the SubmarineCluster.Name will be use for creating the service.
+ ServiceName string `json:"serviceName,omitempty"`
+
+ // PodTemplate contains the pod specificaton that should run the Submarine-server process
+ PodTemplate *kapiv1.PodTemplateSpec `json:"podTemplate,omitempty"`
+
+ // Labels for created Submarine-cluster (deployment, rs, pod) (if any)
+ AdditionalLabels map[string]string `json:"AdditionalLabels,omitempty"`
+
Name string `json:"name"`
School string `json:"school"`
Email string `json:"email"`
Address string `json:"address"`
}
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// SubmarineClusterNode represent a SubmarineCluster Node
+type SubmarineClusterNode struct {
+ ID string `json:"id"`
+ Role SubmarineClusterNodeRole `json:"role"`
+ IP string `json:"ip"`
+ Port string `json:"port"`
+ Slots []string `json:"slots,omitempty"`
+ MasterRef string `json:"masterRef,omitempty"`
+ PodName string `json:"podName"`
+ Pod *kapiv1.Pod `json:"-"`
+}
-// StudentList is a list of Student resources
-type SubmarineServerList struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ListMeta `json:"metadata"`
+func (n SubmarineClusterNode) String() string {
+ if n.Role != SubmarineClusterNodeRoleSlave {
+ return fmt.Sprintf("(Master:%s, Addr:%s:%s, PodName:%s, Slots:%v)", n.ID, n.IP, n.Port, n.PodName, n.Slots)
+ }
+ return fmt.Sprintf("(Slave:%s, Addr:%s:%s, PodName:%s, MasterRef:%s)", n.ID, n.IP, n.Port, n.PodName, n.MasterRef)
+}
+
+// SubmarineClusterConditionType is the type of SubmarineClusterCondition
+type SubmarineClusterConditionType string
+
+const (
+ // SubmarineClusterOK means the SubmarineCluster is in a good shape
+ SubmarineClusterOK SubmarineClusterConditionType = "ClusterOK"
+
+ // SubmarineClusterScaling means the SubmarineCluster is currenlty in a scaling stage
+ SubmarineClusterScaling SubmarineClusterConditionType = "Scaling"
+
+ // SubmarineClusterRebalancing means the SubmarineCluster is currenlty rebalancing slots and keys
+ SubmarineClusterRebalancing SubmarineClusterConditionType = "Rebalancing"
+
+ // SubmarineClusterRollingUpdate means the SubmarineCluster is currenlty performing a rolling update of its nodes
+ SubmarineClusterRollingUpdate SubmarineClusterConditionType = "RollingUpdate"
+)
+
+// SubmarineClusterNodeRole SubmarineCluster Node Role type
+type SubmarineClusterNodeRole string
- Items []SubmarineServer `json:"items"`
+const (
+ // SubmarineClusterNodeRoleMaster SubmarineCluster Master node role
+ SubmarineClusterNodeRoleMaster SubmarineClusterNodeRole = "Master"
+
+ // SubmarineClusterNodeRoleSlave SubmarineCluster Master node role
+ SubmarineClusterNodeRoleSlave SubmarineClusterNodeRole = "Slave"
+
+ // SubmarineClusterNodeRoleNone None node role
+ SubmarineClusterNodeRoleNone SubmarineClusterNodeRole = "None"
+)
+
+// ClusterStatus Submarine Cluster status
+type ClusterStatus string
+
+const (
+ // ClusterStatusOK ClusterStatus OK
+ ClusterStatusOK ClusterStatus = "OK"
+
+ // ClusterStatusError ClusterStatus Error
+ ClusterStatusError ClusterStatus = "Error"
+
+ // ClusterStatusScaling ClusterStatus Scaling
+ ClusterStatusScaling ClusterStatus = "Scaling"
+
+ // ClusterStatusCalculatingRebalancing ClusterStatus Rebalancing
+ ClusterStatusCalculatingRebalancing ClusterStatus = "Calculating Rebalancing"
+
+ // ClusterStatusRebalancing ClusterStatus Rebalancing
+ ClusterStatusRebalancing ClusterStatus = "Rebalancing"
+
+ // ClusterStatusRollingUpdate ClusterStatus RollingUpdate
+ ClusterStatusRollingUpdate ClusterStatus = "RollingUpdate"
+)
+
+// SubmarineClusterStatus contains SubmarineCluster status
+type SubmarineClusterStatus struct {
+ // Conditions represent the latest available observations of an object's current state.
+ Conditions []SubmarineClusterCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
+ // Status of the condition, one of True, False, Unknown.
+ Status kapiv1.ConditionStatus `json:"status"`
+ // StartTime represents time when the workflow was acknowledged by the Workflow controller
+ // It is not guaranteed to be set in happens-before order across separate operations.
+ // It is represented in RFC3339 form and is in UTC.
+ // StartTime doesn't consider startime of `ExternalReference`
+ StartTime *metav1.Time `json:"startTime,omitempty"`
+ // (brief) reason for the condition's last transition.
+ Reason string `json:"reason,omitempty"`
+ // Human readable message indicating details about last transition.
+ Message string `json:"message,omitempty"`
+ // Cluster a view of the current SubmarineCluster
+ Cluster SubmarineClusterClusterStatus
+}
+
+// SubmarineClusterCondition represent the condition of the SubmarineCluster
+type SubmarineClusterCondition struct {
+ // Type of workflow condition
+ Type SubmarineClusterConditionType `json:"type"`
+ // Status of the condition, one of True, False, Unknown.
+ Status kapiv1.ConditionStatus `json:"status"`
+ // Last time the condition was checked.
+ LastProbeTime metav1.Time `json:"lastProbeTime,omitempty"`
+ // Last time the condition transited from one status to another.
+ LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
+ // (brief) reason for the condition's last transition.
+ Reason string `json:"reason,omitempty"`
+ // Human readable message indicating details about last transition.
+ Message string `json:"message,omitempty"`
}
+
+// SubmarineClusterClusterStatus represent the Submarine Cluster status
+type SubmarineClusterClusterStatus struct {
+ Status ClusterStatus `json:"status"`
+ NumberOfMaster int32 `json:"numberOfMaster,omitempty"`
+ MinReplicationFactor int32 `json:"minReplicationFactor,omitempty"`
+ MaxReplicationFactor int32 `json:"maxReplicationFactor,omitempty"`
+
+ NodesPlacement NodesPlacementInfo `json:"nodesPlacementInfo,omitempty"`
+
+ // In theory, we always have NbPods > NbSubmarineRunning > NbPodsReady
+ NbPods int32 `json:"nbPods,omitempty"`
+ NbPodsReady int32 `json:"nbPodsReady,omitempty"`
+ NbSubmarineRunning int32 `json:"nbSubmarineNodesRunning,omitempty"`
+
+ Nodes []SubmarineClusterNode `json:"nodes"`
+}
+
+func (s SubmarineClusterClusterStatus) String() string {
+ output := ""
+ output += fmt.Sprintf("status:%s\n", s.Status)
+ output += fmt.Sprintf("NumberOfMaster:%d\n", s.NumberOfMaster)
+ output += fmt.Sprintf("MinReplicationFactor:%d\n", s.MinReplicationFactor)
+ output += fmt.Sprintf("MaxReplicationFactor:%d\n", s.MaxReplicationFactor)
+ output += fmt.Sprintf("NodesPlacement:%s\n\n", s.NodesPlacement)
+ output += fmt.Sprintf("NbPods:%d\n", s.NbPods)
+ output += fmt.Sprintf("NbPodsReady:%d\n", s.NbPodsReady)
+ output += fmt.Sprintf("NbSubmarineRunning:%d\n\n", s.NbSubmarineRunning)
+
+ output += fmt.Sprintf("Nodes (%d): %s\n", len(s.Nodes), s.Nodes)
+
+ return output
+}
+
+// NodesPlacementInfo Submarine Nodes placement mode information
+type NodesPlacementInfo string
+
+const (
+ // NodesPlacementInfoBestEffort the cluster nodes placement is in best effort,
+ // it means you can have 2 masters (or more) on the same VM.
+ NodesPlacementInfoBestEffort NodesPlacementInfo = "BestEffort"
+ // NodesPlacementInfoOptimal the cluster nodes placement is optimal,
+ // it means on master by VM
+ NodesPlacementInfoOptimal NodesPlacementInfo = "Optimal"
+)
diff --git a/submarine-cloud/pkg/apis/submarine/v1alpha1/zz_generated.deepcopy.go b/submarine-cloud/pkg/apis/submarine/v1alpha1/zz_generated.deepcopy.go
index a24e9b5..7a9fde4 100644
--- a/submarine-cloud/pkg/apis/submarine/v1alpha1/zz_generated.deepcopy.go
+++ b/submarine-cloud/pkg/apis/submarine/v1alpha1/zz_generated.deepcopy.go
@@ -22,30 +22,32 @@
package v1alpha1
import (
+ v1 "k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SubmarineServer) DeepCopyInto(out *SubmarineServer) {
+func (in *SubmarineCluster) DeepCopyInto(out *SubmarineCluster) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
return
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubmarineServer.
-func (in *SubmarineServer) DeepCopy() *SubmarineServer {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubmarineCluster.
+func (in *SubmarineCluster) DeepCopy() *SubmarineCluster {
if in == nil {
return nil
}
- out := new(SubmarineServer)
+ out := new(SubmarineCluster)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *SubmarineServer) DeepCopyObject() runtime.Object {
+func (in *SubmarineCluster) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
@@ -53,13 +55,54 @@ func (in *SubmarineServer) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SubmarineServerList) DeepCopyInto(out *SubmarineServerList) {
+func (in *SubmarineClusterClusterStatus) DeepCopyInto(out *SubmarineClusterClusterStatus) {
+ *out = *in
+ if in.Nodes != nil {
+ in, out := &in.Nodes, &out.Nodes
+ *out = make([]SubmarineClusterNode, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubmarineClusterClusterStatus.
+func (in *SubmarineClusterClusterStatus) DeepCopy() *SubmarineClusterClusterStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(SubmarineClusterClusterStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SubmarineClusterCondition) DeepCopyInto(out *SubmarineClusterCondition) {
+ *out = *in
+ in.LastProbeTime.DeepCopyInto(&out.LastProbeTime)
+ in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubmarineClusterCondition.
+func (in *SubmarineClusterCondition) DeepCopy() *SubmarineClusterCondition {
+ if in == nil {
+ return nil
+ }
+ out := new(SubmarineClusterCondition)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SubmarineClusterList) DeepCopyInto(out *SubmarineClusterList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
- *out = make([]SubmarineServer, len(*in))
+ *out = make([]SubmarineCluster, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -67,18 +110,18 @@ func (in *SubmarineServerList) DeepCopyInto(out *SubmarineServerList) {
return
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubmarineServerList.
-func (in *SubmarineServerList) DeepCopy() *SubmarineServerList {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubmarineClusterList.
+func (in *SubmarineClusterList) DeepCopy() *SubmarineClusterList {
if in == nil {
return nil
}
- out := new(SubmarineServerList)
+ out := new(SubmarineClusterList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *SubmarineServerList) DeepCopyObject() runtime.Object {
+func (in *SubmarineClusterList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
@@ -86,17 +129,93 @@ func (in *SubmarineServerList) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SubmarineServerSpec) DeepCopyInto(out *SubmarineServerSpec) {
+func (in *SubmarineClusterNode) DeepCopyInto(out *SubmarineClusterNode) {
+ *out = *in
+ if in.Slots != nil {
+ in, out := &in.Slots, &out.Slots
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ if in.Pod != nil {
+ in, out := &in.Pod, &out.Pod
+ *out = new(v1.Pod)
+ (*in).DeepCopyInto(*out)
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubmarineClusterNode.
+func (in *SubmarineClusterNode) DeepCopy() *SubmarineClusterNode {
+ if in == nil {
+ return nil
+ }
+ out := new(SubmarineClusterNode)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SubmarineClusterSpec) DeepCopyInto(out *SubmarineClusterSpec) {
+ *out = *in
+ if in.NumberOfMaster != nil {
+ in, out := &in.NumberOfMaster, &out.NumberOfMaster
+ *out = new(int32)
+ **out = **in
+ }
+ if in.ReplicationFactor != nil {
+ in, out := &in.ReplicationFactor, &out.ReplicationFactor
+ *out = new(int32)
+ **out = **in
+ }
+ if in.PodTemplate != nil {
+ in, out := &in.PodTemplate, &out.PodTemplate
+ *out = new(v1.PodTemplateSpec)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.AdditionalLabels != nil {
+ in, out := &in.AdditionalLabels, &out.AdditionalLabels
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubmarineClusterSpec.
+func (in *SubmarineClusterSpec) DeepCopy() *SubmarineClusterSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(SubmarineClusterSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SubmarineClusterStatus) DeepCopyInto(out *SubmarineClusterStatus) {
*out = *in
+ if in.Conditions != nil {
+ in, out := &in.Conditions, &out.Conditions
+ *out = make([]SubmarineClusterCondition, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.StartTime != nil {
+ in, out := &in.StartTime, &out.StartTime
+ *out = (*in).DeepCopy()
+ }
+ in.Cluster.DeepCopyInto(&out.Cluster)
return
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubmarineServerSpec.
-func (in *SubmarineServerSpec) DeepCopy() *SubmarineServerSpec {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubmarineClusterStatus.
+func (in *SubmarineClusterStatus) DeepCopy() *SubmarineClusterStatus {
if in == nil {
return nil
}
- out := new(SubmarineServerSpec)
+ out := new(SubmarineClusterStatus)
in.DeepCopyInto(out)
return out
}
diff --git a/submarine-cloud/pkg/client/client.go b/submarine-cloud/pkg/client/client.go
new file mode 100644
index 0000000..3e04db2
--- /dev/null
+++ b/submarine-cloud/pkg/client/client.go
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package client
+
+import (
+ "reflect"
+ "time"
+
+ apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
+ 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/serializer"
+ "k8s.io/apimachinery/pkg/util/errors"
+ "k8s.io/apimachinery/pkg/util/wait"
+ "k8s.io/client-go/rest"
+
+ "github.com/golang/glog"
+
+ "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine"
+ v1 "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
+ "github.com/apache/submarine/submarine-cloud/pkg/client/clientset/versioned"
+)
+
+// DefineSubmarineClusterResource defines a SubmarineClusterResource as a k8s CR
+func DefineSubmarineClusterResource(clientset apiextensionsclient.Interface) (*apiextensionsv1beta1.CustomResourceDefinition, error) {
+ glog.Info("DefineSubmarineClusterResource()")
+ submarineClusterResourceName := v1.ResourcePlural + "." + submarine.GroupName
+ crd := &apiextensionsv1beta1.CustomResourceDefinition{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: submarineClusterResourceName,
+ },
+ Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
+ Group: submarine.GroupName,
+ Version: v1.SchemeGroupVersion.Version,
+ Scope: apiextensionsv1beta1.NamespaceScoped,
+ Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
+ Plural: v1.ResourcePlural,
+ Singular: v1.ResourceSingular,
+ Kind: reflect.TypeOf(v1.SubmarineCluster{}).Name(),
+ ShortNames: []string{"submarine"},
+ },
+ },
+ }
+ _, err := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd)
+ if err != nil {
+ return nil, err
+ }
+
+ // wait for CRD being established
+ err = wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) {
+ crd, err = clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Get(submarineClusterResourceName, metav1.GetOptions{})
+ if err != nil {
+ return false, err
+ }
+ for _, cond := range crd.Status.Conditions {
+ switch cond.Type {
+ case apiextensionsv1beta1.Established:
+ if cond.Status == apiextensionsv1beta1.ConditionTrue {
+ return true, err
+ }
+ case apiextensionsv1beta1.NamesAccepted:
+ if cond.Status == apiextensionsv1beta1.ConditionFalse {
+ glog.Errorf("Name conflict: %v\n", cond.Reason)
+ }
+ }
+ }
+ return false, err
+ })
+ if err != nil {
+ deleteErr := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Delete(submarineClusterResourceName, nil)
+ if deleteErr != nil {
+ return nil, errors.NewAggregate([]error{err, deleteErr})
+ }
+ return nil, err
+ }
+
+ return crd, nil
+}
+
+// NewClient builds and initializes a Client and a Scheme for SubmarineCluster CR
+func NewClient(cfg *rest.Config) (versioned.Interface, error) {
+ glog.Info("NewClient()")
+ scheme := runtime.NewScheme()
+ if err := v1.AddToScheme(scheme); err != nil {
+ return nil, err
+ }
+
+ config := *cfg
+ config.GroupVersion = &v1.SchemeGroupVersion
+ config.APIPath = "/apis"
+ config.ContentType = runtime.ContentTypeJSON
+ config.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: serializer.NewCodecFactory(scheme)}
+
+ cs, err := versioned.NewForConfig(&config)
+ if err != nil {
+ return nil, err
+ }
+ return cs, nil
+}
diff --git a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/fake/fake_submarine_client.go b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/fake/fake_submarine_client.go
index 90abcd4..883949b 100644
--- a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/fake/fake_submarine_client.go
+++ b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/fake/fake_submarine_client.go
@@ -29,8 +29,8 @@ type FakeSubmarineV1alpha1 struct {
*testing.Fake
}
-func (c *FakeSubmarineV1alpha1) SubmarineServers(namespace string) v1alpha1.SubmarineServerInterface {
- return &FakeSubmarineServers{c, namespace}
+func (c *FakeSubmarineV1alpha1) SubmarineClusters(namespace string) v1alpha1.SubmarineClusterInterface {
+ return &FakeSubmarineClusters{c, namespace}
}
// RESTClient returns a RESTClient that is used to communicate
diff --git a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/fake/fake_submarinecluster.go b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/fake/fake_submarinecluster.go
new file mode 100644
index 0000000..b45545c
--- /dev/null
+++ b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/fake/fake_submarinecluster.go
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+ v1alpha1 "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ labels "k8s.io/apimachinery/pkg/labels"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ testing "k8s.io/client-go/testing"
+)
+
+// FakeSubmarineClusters implements SubmarineClusterInterface
+type FakeSubmarineClusters struct {
+ Fake *FakeSubmarineV1alpha1
+ ns string
+}
+
+var submarineclustersResource = schema.GroupVersionResource{Group: "submarine.apache.org", Version: "v1alpha1", Resource: "submarineclusters"}
+
+var submarineclustersKind = schema.GroupVersionKind{Group: "submarine.apache.org", Version: "v1alpha1", Kind: "SubmarineCluster"}
+
+// Get takes name of the submarineCluster, and returns the corresponding submarineCluster object, and an error if there is any.
+func (c *FakeSubmarineClusters) Get(name string, options v1.GetOptions) (result *v1alpha1.SubmarineCluster, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewGetAction(submarineclustersResource, c.ns, name), &v1alpha1.SubmarineCluster{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.SubmarineCluster), err
+}
+
+// List takes label and field selectors, and returns the list of SubmarineClusters that match those selectors.
+func (c *FakeSubmarineClusters) List(opts v1.ListOptions) (result *v1alpha1.SubmarineClusterList, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewListAction(submarineclustersResource, submarineclustersKind, c.ns, opts), &v1alpha1.SubmarineClusterList{})
+
+ if obj == nil {
+ return nil, err
+ }
+
+ label, _, _ := testing.ExtractFromListOptions(opts)
+ if label == nil {
+ label = labels.Everything()
+ }
+ list := &v1alpha1.SubmarineClusterList{ListMeta: obj.(*v1alpha1.SubmarineClusterList).ListMeta}
+ for _, item := range obj.(*v1alpha1.SubmarineClusterList).Items {
+ if label.Matches(labels.Set(item.Labels)) {
+ list.Items = append(list.Items, item)
+ }
+ }
+ return list, err
+}
+
+// Watch returns a watch.Interface that watches the requested submarineClusters.
+func (c *FakeSubmarineClusters) Watch(opts v1.ListOptions) (watch.Interface, error) {
+ return c.Fake.
+ InvokesWatch(testing.NewWatchAction(submarineclustersResource, c.ns, opts))
+
+}
+
+// Create takes the representation of a submarineCluster and creates it. Returns the server's representation of the submarineCluster, and an error, if there is any.
+func (c *FakeSubmarineClusters) Create(submarineCluster *v1alpha1.SubmarineCluster) (result *v1alpha1.SubmarineCluster, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewCreateAction(submarineclustersResource, c.ns, submarineCluster), &v1alpha1.SubmarineCluster{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.SubmarineCluster), err
+}
+
+// Update takes the representation of a submarineCluster and updates it. Returns the server's representation of the submarineCluster, and an error, if there is any.
+func (c *FakeSubmarineClusters) Update(submarineCluster *v1alpha1.SubmarineCluster) (result *v1alpha1.SubmarineCluster, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewUpdateAction(submarineclustersResource, c.ns, submarineCluster), &v1alpha1.SubmarineCluster{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.SubmarineCluster), err
+}
+
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+func (c *FakeSubmarineClusters) UpdateStatus(submarineCluster *v1alpha1.SubmarineCluster) (*v1alpha1.SubmarineCluster, error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewUpdateSubresourceAction(submarineclustersResource, "status", c.ns, submarineCluster), &v1alpha1.SubmarineCluster{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.SubmarineCluster), err
+}
+
+// Delete takes name of the submarineCluster and deletes it. Returns an error if one occurs.
+func (c *FakeSubmarineClusters) Delete(name string, options *v1.DeleteOptions) error {
+ _, err := c.Fake.
+ Invokes(testing.NewDeleteAction(submarineclustersResource, c.ns, name), &v1alpha1.SubmarineCluster{})
+
+ return err
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *FakeSubmarineClusters) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
+ action := testing.NewDeleteCollectionAction(submarineclustersResource, c.ns, listOptions)
+
+ _, err := c.Fake.Invokes(action, &v1alpha1.SubmarineClusterList{})
+ return err
+}
+
+// Patch applies the patch and returns the patched submarineCluster.
+func (c *FakeSubmarineClusters) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.SubmarineCluster, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewPatchSubresourceAction(submarineclustersResource, c.ns, name, pt, data, subresources...), &v1alpha1.SubmarineCluster{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.SubmarineCluster), err
+}
diff --git a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/fake/fake_submarineserver.go b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/fake/fake_submarineserver.go
deleted file mode 100644
index f6aa963..0000000
--- a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/fake/fake_submarineserver.go
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-// Code generated by client-gen. DO NOT EDIT.
-
-package fake
-
-import (
- v1alpha1 "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- labels "k8s.io/apimachinery/pkg/labels"
- schema "k8s.io/apimachinery/pkg/runtime/schema"
- types "k8s.io/apimachinery/pkg/types"
- watch "k8s.io/apimachinery/pkg/watch"
- testing "k8s.io/client-go/testing"
-)
-
-// FakeSubmarineServers implements SubmarineServerInterface
-type FakeSubmarineServers struct {
- Fake *FakeSubmarineV1alpha1
- ns string
-}
-
-var submarineserversResource = schema.GroupVersionResource{Group: "submarine.apache.org", Version: "v1alpha1", Resource: "submarineservers"}
-
-var submarineserversKind = schema.GroupVersionKind{Group: "submarine.apache.org", Version: "v1alpha1", Kind: "SubmarineServer"}
-
-// Get takes name of the submarineServer, and returns the corresponding submarineServer object, and an error if there is any.
-func (c *FakeSubmarineServers) Get(name string, options v1.GetOptions) (result *v1alpha1.SubmarineServer, err error) {
- obj, err := c.Fake.
- Invokes(testing.NewGetAction(submarineserversResource, c.ns, name), &v1alpha1.SubmarineServer{})
-
- if obj == nil {
- return nil, err
- }
- return obj.(*v1alpha1.SubmarineServer), err
-}
-
-// List takes label and field selectors, and returns the list of SubmarineServers that match those selectors.
-func (c *FakeSubmarineServers) List(opts v1.ListOptions) (result *v1alpha1.SubmarineServerList, err error) {
- obj, err := c.Fake.
- Invokes(testing.NewListAction(submarineserversResource, submarineserversKind, c.ns, opts), &v1alpha1.SubmarineServerList{})
-
- if obj == nil {
- return nil, err
- }
-
- label, _, _ := testing.ExtractFromListOptions(opts)
- if label == nil {
- label = labels.Everything()
- }
- list := &v1alpha1.SubmarineServerList{ListMeta: obj.(*v1alpha1.SubmarineServerList).ListMeta}
- for _, item := range obj.(*v1alpha1.SubmarineServerList).Items {
- if label.Matches(labels.Set(item.Labels)) {
- list.Items = append(list.Items, item)
- }
- }
- return list, err
-}
-
-// Watch returns a watch.Interface that watches the requested submarineServers.
-func (c *FakeSubmarineServers) Watch(opts v1.ListOptions) (watch.Interface, error) {
- return c.Fake.
- InvokesWatch(testing.NewWatchAction(submarineserversResource, c.ns, opts))
-
-}
-
-// Create takes the representation of a submarineServer and creates it. Returns the server's representation of the submarineServer, and an error, if there is any.
-func (c *FakeSubmarineServers) Create(submarineServer *v1alpha1.SubmarineServer) (result *v1alpha1.SubmarineServer, err error) {
- obj, err := c.Fake.
- Invokes(testing.NewCreateAction(submarineserversResource, c.ns, submarineServer), &v1alpha1.SubmarineServer{})
-
- if obj == nil {
- return nil, err
- }
- return obj.(*v1alpha1.SubmarineServer), err
-}
-
-// Update takes the representation of a submarineServer and updates it. Returns the server's representation of the submarineServer, and an error, if there is any.
-func (c *FakeSubmarineServers) Update(submarineServer *v1alpha1.SubmarineServer) (result *v1alpha1.SubmarineServer, err error) {
- obj, err := c.Fake.
- Invokes(testing.NewUpdateAction(submarineserversResource, c.ns, submarineServer), &v1alpha1.SubmarineServer{})
-
- if obj == nil {
- return nil, err
- }
- return obj.(*v1alpha1.SubmarineServer), err
-}
-
-// Delete takes name of the submarineServer and deletes it. Returns an error if one occurs.
-func (c *FakeSubmarineServers) Delete(name string, options *v1.DeleteOptions) error {
- _, err := c.Fake.
- Invokes(testing.NewDeleteAction(submarineserversResource, c.ns, name), &v1alpha1.SubmarineServer{})
-
- return err
-}
-
-// DeleteCollection deletes a collection of objects.
-func (c *FakeSubmarineServers) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
- action := testing.NewDeleteCollectionAction(submarineserversResource, c.ns, listOptions)
-
- _, err := c.Fake.Invokes(action, &v1alpha1.SubmarineServerList{})
- return err
-}
-
-// Patch applies the patch and returns the patched submarineServer.
-func (c *FakeSubmarineServers) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.SubmarineServer, err error) {
- obj, err := c.Fake.
- Invokes(testing.NewPatchSubresourceAction(submarineserversResource, c.ns, name, pt, data, subresources...), &v1alpha1.SubmarineServer{})
-
- if obj == nil {
- return nil, err
- }
- return obj.(*v1alpha1.SubmarineServer), err
-}
diff --git a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/generated_expansion.go b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/generated_expansion.go
index 0ede7ea..67abfe0 100644
--- a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/generated_expansion.go
+++ b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/generated_expansion.go
@@ -19,4 +19,4 @@
package v1alpha1
-type SubmarineServerExpansion interface{}
+type SubmarineClusterExpansion interface{}
diff --git a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/submarine_client.go b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/submarine_client.go
index 286fea9..f45bc70 100644
--- a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/submarine_client.go
+++ b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/submarine_client.go
@@ -27,7 +27,7 @@ import (
type SubmarineV1alpha1Interface interface {
RESTClient() rest.Interface
- SubmarineServersGetter
+ SubmarineClustersGetter
}
// SubmarineV1alpha1Client is used to interact with features provided by the submarine.apache.org group.
@@ -35,8 +35,8 @@ type SubmarineV1alpha1Client struct {
restClient rest.Interface
}
-func (c *SubmarineV1alpha1Client) SubmarineServers(namespace string) SubmarineServerInterface {
- return newSubmarineServers(c, namespace)
+func (c *SubmarineV1alpha1Client) SubmarineClusters(namespace string) SubmarineClusterInterface {
+ return newSubmarineClusters(c, namespace)
}
// NewForConfig creates a new SubmarineV1alpha1Client for the given config.
diff --git a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/submarinecluster.go b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/submarinecluster.go
new file mode 100644
index 0000000..d72fa81
--- /dev/null
+++ b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/submarinecluster.go
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ "time"
+
+ v1alpha1 "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
+ scheme "github.com/apache/submarine/submarine-cloud/pkg/client/clientset/versioned/scheme"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ rest "k8s.io/client-go/rest"
+)
+
+// SubmarineClustersGetter has a method to return a SubmarineClusterInterface.
+// A group's client should implement this interface.
+type SubmarineClustersGetter interface {
+ SubmarineClusters(namespace string) SubmarineClusterInterface
+}
+
+// SubmarineClusterInterface has methods to work with SubmarineCluster resources.
+type SubmarineClusterInterface interface {
+ Create(*v1alpha1.SubmarineCluster) (*v1alpha1.SubmarineCluster, error)
+ Update(*v1alpha1.SubmarineCluster) (*v1alpha1.SubmarineCluster, error)
+ UpdateStatus(*v1alpha1.SubmarineCluster) (*v1alpha1.SubmarineCluster, error)
+ Delete(name string, options *v1.DeleteOptions) error
+ DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
+ Get(name string, options v1.GetOptions) (*v1alpha1.SubmarineCluster, error)
+ List(opts v1.ListOptions) (*v1alpha1.SubmarineClusterList, error)
+ Watch(opts v1.ListOptions) (watch.Interface, error)
+ Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.SubmarineCluster, err error)
+ SubmarineClusterExpansion
+}
+
+// submarineClusters implements SubmarineClusterInterface
+type submarineClusters struct {
+ client rest.Interface
+ ns string
+}
+
+// newSubmarineClusters returns a SubmarineClusters
+func newSubmarineClusters(c *SubmarineV1alpha1Client, namespace string) *submarineClusters {
+ return &submarineClusters{
+ client: c.RESTClient(),
+ ns: namespace,
+ }
+}
+
+// Get takes name of the submarineCluster, and returns the corresponding submarineCluster object, and an error if there is any.
+func (c *submarineClusters) Get(name string, options v1.GetOptions) (result *v1alpha1.SubmarineCluster, err error) {
+ result = &v1alpha1.SubmarineCluster{}
+ err = c.client.Get().
+ Namespace(c.ns).
+ Resource("submarineclusters").
+ Name(name).
+ VersionedParams(&options, scheme.ParameterCodec).
+ Do().
+ Into(result)
+ return
+}
+
+// List takes label and field selectors, and returns the list of SubmarineClusters that match those selectors.
+func (c *submarineClusters) List(opts v1.ListOptions) (result *v1alpha1.SubmarineClusterList, err error) {
+ var timeout time.Duration
+ if opts.TimeoutSeconds != nil {
+ timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+ }
+ result = &v1alpha1.SubmarineClusterList{}
+ err = c.client.Get().
+ Namespace(c.ns).
+ Resource("submarineclusters").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Timeout(timeout).
+ Do().
+ Into(result)
+ return
+}
+
+// Watch returns a watch.Interface that watches the requested submarineClusters.
+func (c *submarineClusters) Watch(opts v1.ListOptions) (watch.Interface, error) {
+ var timeout time.Duration
+ if opts.TimeoutSeconds != nil {
+ timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+ }
+ opts.Watch = true
+ return c.client.Get().
+ Namespace(c.ns).
+ Resource("submarineclusters").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Timeout(timeout).
+ Watch()
+}
+
+// Create takes the representation of a submarineCluster and creates it. Returns the server's representation of the submarineCluster, and an error, if there is any.
+func (c *submarineClusters) Create(submarineCluster *v1alpha1.SubmarineCluster) (result *v1alpha1.SubmarineCluster, err error) {
+ result = &v1alpha1.SubmarineCluster{}
+ err = c.client.Post().
+ Namespace(c.ns).
+ Resource("submarineclusters").
+ Body(submarineCluster).
+ Do().
+ Into(result)
+ return
+}
+
+// Update takes the representation of a submarineCluster and updates it. Returns the server's representation of the submarineCluster, and an error, if there is any.
+func (c *submarineClusters) Update(submarineCluster *v1alpha1.SubmarineCluster) (result *v1alpha1.SubmarineCluster, err error) {
+ result = &v1alpha1.SubmarineCluster{}
+ err = c.client.Put().
+ Namespace(c.ns).
+ Resource("submarineclusters").
+ Name(submarineCluster.Name).
+ Body(submarineCluster).
+ Do().
+ Into(result)
+ return
+}
+
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+
+func (c *submarineClusters) UpdateStatus(submarineCluster *v1alpha1.SubmarineCluster) (result *v1alpha1.SubmarineCluster, err error) {
+ result = &v1alpha1.SubmarineCluster{}
+ err = c.client.Put().
+ Namespace(c.ns).
+ Resource("submarineclusters").
+ Name(submarineCluster.Name).
+ SubResource("status").
+ Body(submarineCluster).
+ Do().
+ Into(result)
+ return
+}
+
+// Delete takes name of the submarineCluster and deletes it. Returns an error if one occurs.
+func (c *submarineClusters) Delete(name string, options *v1.DeleteOptions) error {
+ return c.client.Delete().
+ Namespace(c.ns).
+ Resource("submarineclusters").
+ Name(name).
+ Body(options).
+ Do().
+ Error()
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *submarineClusters) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
+ var timeout time.Duration
+ if listOptions.TimeoutSeconds != nil {
+ timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
+ }
+ return c.client.Delete().
+ Namespace(c.ns).
+ Resource("submarineclusters").
+ VersionedParams(&listOptions, scheme.ParameterCodec).
+ Timeout(timeout).
+ Body(options).
+ Do().
+ Error()
+}
+
+// Patch applies the patch and returns the patched submarineCluster.
+func (c *submarineClusters) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.SubmarineCluster, err error) {
+ result = &v1alpha1.SubmarineCluster{}
+ err = c.client.Patch(pt).
+ Namespace(c.ns).
+ Resource("submarineclusters").
+ SubResource(subresources...).
+ Name(name).
+ Body(data).
+ Do().
+ Into(result)
+ return
+}
diff --git a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/submarineserver.go b/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/submarineserver.go
deleted file mode 100644
index 1d89515..0000000
--- a/submarine-cloud/pkg/client/clientset/versioned/typed/submarine/v1alpha1/submarineserver.go
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-// Code generated by client-gen. DO NOT EDIT.
-
-package v1alpha1
-
-import (
- "time"
-
- v1alpha1 "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
- scheme "github.com/apache/submarine/submarine-cloud/pkg/client/clientset/versioned/scheme"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- types "k8s.io/apimachinery/pkg/types"
- watch "k8s.io/apimachinery/pkg/watch"
- rest "k8s.io/client-go/rest"
-)
-
-// SubmarineServersGetter has a method to return a SubmarineServerInterface.
-// A group's client should implement this interface.
-type SubmarineServersGetter interface {
- SubmarineServers(namespace string) SubmarineServerInterface
-}
-
-// SubmarineServerInterface has methods to work with SubmarineServer resources.
-type SubmarineServerInterface interface {
- Create(*v1alpha1.SubmarineServer) (*v1alpha1.SubmarineServer, error)
- Update(*v1alpha1.SubmarineServer) (*v1alpha1.SubmarineServer, error)
- Delete(name string, options *v1.DeleteOptions) error
- DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
- Get(name string, options v1.GetOptions) (*v1alpha1.SubmarineServer, error)
- List(opts v1.ListOptions) (*v1alpha1.SubmarineServerList, error)
- Watch(opts v1.ListOptions) (watch.Interface, error)
- Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.SubmarineServer, err error)
- SubmarineServerExpansion
-}
-
-// submarineServers implements SubmarineServerInterface
-type submarineServers struct {
- client rest.Interface
- ns string
-}
-
-// newSubmarineServers returns a SubmarineServers
-func newSubmarineServers(c *SubmarineV1alpha1Client, namespace string) *submarineServers {
- return &submarineServers{
- client: c.RESTClient(),
- ns: namespace,
- }
-}
-
-// Get takes name of the submarineServer, and returns the corresponding submarineServer object, and an error if there is any.
-func (c *submarineServers) Get(name string, options v1.GetOptions) (result *v1alpha1.SubmarineServer, err error) {
- result = &v1alpha1.SubmarineServer{}
- err = c.client.Get().
- Namespace(c.ns).
- Resource("submarineservers").
- Name(name).
- VersionedParams(&options, scheme.ParameterCodec).
- Do().
- Into(result)
- return
-}
-
-// List takes label and field selectors, and returns the list of SubmarineServers that match those selectors.
-func (c *submarineServers) List(opts v1.ListOptions) (result *v1alpha1.SubmarineServerList, err error) {
- var timeout time.Duration
- if opts.TimeoutSeconds != nil {
- timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
- }
- result = &v1alpha1.SubmarineServerList{}
- err = c.client.Get().
- Namespace(c.ns).
- Resource("submarineservers").
- VersionedParams(&opts, scheme.ParameterCodec).
- Timeout(timeout).
- Do().
- Into(result)
- return
-}
-
-// Watch returns a watch.Interface that watches the requested submarineServers.
-func (c *submarineServers) Watch(opts v1.ListOptions) (watch.Interface, error) {
- var timeout time.Duration
- if opts.TimeoutSeconds != nil {
- timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
- }
- opts.Watch = true
- return c.client.Get().
- Namespace(c.ns).
- Resource("submarineservers").
- VersionedParams(&opts, scheme.ParameterCodec).
- Timeout(timeout).
- Watch()
-}
-
-// Create takes the representation of a submarineServer and creates it. Returns the server's representation of the submarineServer, and an error, if there is any.
-func (c *submarineServers) Create(submarineServer *v1alpha1.SubmarineServer) (result *v1alpha1.SubmarineServer, err error) {
- result = &v1alpha1.SubmarineServer{}
- err = c.client.Post().
- Namespace(c.ns).
- Resource("submarineservers").
- Body(submarineServer).
- Do().
- Into(result)
- return
-}
-
-// Update takes the representation of a submarineServer and updates it. Returns the server's representation of the submarineServer, and an error, if there is any.
-func (c *submarineServers) Update(submarineServer *v1alpha1.SubmarineServer) (result *v1alpha1.SubmarineServer, err error) {
- result = &v1alpha1.SubmarineServer{}
- err = c.client.Put().
- Namespace(c.ns).
- Resource("submarineservers").
- Name(submarineServer.Name).
- Body(submarineServer).
- Do().
- Into(result)
- return
-}
-
-// Delete takes name of the submarineServer and deletes it. Returns an error if one occurs.
-func (c *submarineServers) Delete(name string, options *v1.DeleteOptions) error {
- return c.client.Delete().
- Namespace(c.ns).
- Resource("submarineservers").
- Name(name).
- Body(options).
- Do().
- Error()
-}
-
-// DeleteCollection deletes a collection of objects.
-func (c *submarineServers) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
- var timeout time.Duration
- if listOptions.TimeoutSeconds != nil {
- timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
- }
- return c.client.Delete().
- Namespace(c.ns).
- Resource("submarineservers").
- VersionedParams(&listOptions, scheme.ParameterCodec).
- Timeout(timeout).
- Body(options).
- Do().
- Error()
-}
-
-// Patch applies the patch and returns the patched submarineServer.
-func (c *submarineServers) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.SubmarineServer, err error) {
- result = &v1alpha1.SubmarineServer{}
- err = c.client.Patch(pt).
- Namespace(c.ns).
- Resource("submarineservers").
- SubResource(subresources...).
- Name(name).
- Body(data).
- Do().
- Into(result)
- return
-}
diff --git a/submarine-cloud/pkg/client/informers/externalversions/generic.go b/submarine-cloud/pkg/client/informers/externalversions/generic.go
index 58c49d3..bbf7ac7 100644
--- a/submarine-cloud/pkg/client/informers/externalversions/generic.go
+++ b/submarine-cloud/pkg/client/informers/externalversions/generic.go
@@ -54,8 +54,8 @@ func (f *genericInformer) Lister() cache.GenericLister {
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
switch resource {
// Group=submarine.apache.org, Version=v1alpha1
- case v1alpha1.SchemeGroupVersion.WithResource("submarineservers"):
- return &genericInformer{resource: resource.GroupResource(), informer: f.Submarine().V1alpha1().SubmarineServers().Informer()}, nil
+ case v1alpha1.SchemeGroupVersion.WithResource("submarineclusters"):
+ return &genericInformer{resource: resource.GroupResource(), informer: f.Submarine().V1alpha1().SubmarineClusters().Informer()}, nil
}
diff --git a/submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1/interface.go b/submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1/interface.go
index 04288b2..59af52f 100644
--- a/submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1/interface.go
+++ b/submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1/interface.go
@@ -25,8 +25,8 @@ import (
// Interface provides access to all the informers in this group version.
type Interface interface {
- // SubmarineServers returns a SubmarineServerInformer.
- SubmarineServers() SubmarineServerInformer
+ // SubmarineClusters returns a SubmarineClusterInformer.
+ SubmarineClusters() SubmarineClusterInformer
}
type version struct {
@@ -40,7 +40,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
-// SubmarineServers returns a SubmarineServerInformer.
-func (v *version) SubmarineServers() SubmarineServerInformer {
- return &submarineServerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
+// SubmarineClusters returns a SubmarineClusterInformer.
+func (v *version) SubmarineClusters() SubmarineClusterInformer {
+ return &submarineClusterInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
diff --git a/submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1/submarineserver.go b/submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1/submarinecluster.go
similarity index 58%
rename from submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1/submarineserver.go
rename to submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1/submarinecluster.go
index b9f663b..35c510e 100644
--- a/submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1/submarineserver.go
+++ b/submarine-cloud/pkg/client/informers/externalversions/submarine/v1alpha1/submarinecluster.go
@@ -32,59 +32,59 @@ import (
cache "k8s.io/client-go/tools/cache"
)
-// SubmarineServerInformer provides access to a shared informer and lister for
-// SubmarineServers.
-type SubmarineServerInformer interface {
+// SubmarineClusterInformer provides access to a shared informer and lister for
+// SubmarineClusters.
+type SubmarineClusterInformer interface {
Informer() cache.SharedIndexInformer
- Lister() v1alpha1.SubmarineServerLister
+ Lister() v1alpha1.SubmarineClusterLister
}
-type submarineServerInformer struct {
+type submarineClusterInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
namespace string
}
-// NewSubmarineServerInformer constructs a new informer for SubmarineServer type.
+// NewSubmarineClusterInformer constructs a new informer for SubmarineCluster type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
-func NewSubmarineServerInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
- return NewFilteredSubmarineServerInformer(client, namespace, resyncPeriod, indexers, nil)
+func NewSubmarineClusterInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+ return NewFilteredSubmarineClusterInformer(client, namespace, resyncPeriod, indexers, nil)
}
-// NewFilteredSubmarineServerInformer constructs a new informer for SubmarineServer type.
+// NewFilteredSubmarineClusterInformer constructs a new informer for SubmarineCluster type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
-func NewFilteredSubmarineServerInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
+func NewFilteredSubmarineClusterInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
- return client.SubmarineV1alpha1().SubmarineServers(namespace).List(options)
+ return client.SubmarineV1alpha1().SubmarineClusters(namespace).List(options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
- return client.SubmarineV1alpha1().SubmarineServers(namespace).Watch(options)
+ return client.SubmarineV1alpha1().SubmarineClusters(namespace).Watch(options)
},
},
- &submarinev1alpha1.SubmarineServer{},
+ &submarinev1alpha1.SubmarineCluster{},
resyncPeriod,
indexers,
)
}
-func (f *submarineServerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
- return NewFilteredSubmarineServerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
+func (f *submarineClusterInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
+ return NewFilteredSubmarineClusterInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
-func (f *submarineServerInformer) Informer() cache.SharedIndexInformer {
- return f.factory.InformerFor(&submarinev1alpha1.SubmarineServer{}, f.defaultInformer)
+func (f *submarineClusterInformer) Informer() cache.SharedIndexInformer {
+ return f.factory.InformerFor(&submarinev1alpha1.SubmarineCluster{}, f.defaultInformer)
}
-func (f *submarineServerInformer) Lister() v1alpha1.SubmarineServerLister {
- return v1alpha1.NewSubmarineServerLister(f.Informer().GetIndexer())
+func (f *submarineClusterInformer) Lister() v1alpha1.SubmarineClusterLister {
+ return v1alpha1.NewSubmarineClusterLister(f.Informer().GetIndexer())
}
diff --git a/submarine-cloud/pkg/client/listers/submarine/v1alpha1/expansion_generated.go b/submarine-cloud/pkg/client/listers/submarine/v1alpha1/expansion_generated.go
index 8cd2035..1265463 100644
--- a/submarine-cloud/pkg/client/listers/submarine/v1alpha1/expansion_generated.go
+++ b/submarine-cloud/pkg/client/listers/submarine/v1alpha1/expansion_generated.go
@@ -19,10 +19,10 @@
package v1alpha1
-// SubmarineServerListerExpansion allows custom methods to be added to
-// SubmarineServerLister.
-type SubmarineServerListerExpansion interface{}
+// SubmarineClusterListerExpansion allows custom methods to be added to
+// SubmarineClusterLister.
+type SubmarineClusterListerExpansion interface{}
-// SubmarineServerNamespaceListerExpansion allows custom methods to be added to
-// SubmarineServerNamespaceLister.
-type SubmarineServerNamespaceListerExpansion interface{}
+// SubmarineClusterNamespaceListerExpansion allows custom methods to be added to
+// SubmarineClusterNamespaceLister.
+type SubmarineClusterNamespaceListerExpansion interface{}
diff --git a/submarine-cloud/pkg/client/listers/submarine/v1alpha1/submarinecluster.go b/submarine-cloud/pkg/client/listers/submarine/v1alpha1/submarinecluster.go
new file mode 100644
index 0000000..f2acaa3
--- /dev/null
+++ b/submarine-cloud/pkg/client/listers/submarine/v1alpha1/submarinecluster.go
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+ v1alpha1 "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/client-go/tools/cache"
+)
+
+// SubmarineClusterLister helps list SubmarineClusters.
+type SubmarineClusterLister interface {
+ // List lists all SubmarineClusters in the indexer.
+ List(selector labels.Selector) (ret []*v1alpha1.SubmarineCluster, err error)
+ // SubmarineClusters returns an object that can list and get SubmarineClusters.
+ SubmarineClusters(namespace string) SubmarineClusterNamespaceLister
+ SubmarineClusterListerExpansion
+}
+
+// submarineClusterLister implements the SubmarineClusterLister interface.
+type submarineClusterLister struct {
+ indexer cache.Indexer
+}
+
+// NewSubmarineClusterLister returns a new SubmarineClusterLister.
+func NewSubmarineClusterLister(indexer cache.Indexer) SubmarineClusterLister {
+ return &submarineClusterLister{indexer: indexer}
+}
+
+// List lists all SubmarineClusters in the indexer.
+func (s *submarineClusterLister) List(selector labels.Selector) (ret []*v1alpha1.SubmarineCluster, err error) {
+ err = cache.ListAll(s.indexer, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1alpha1.SubmarineCluster))
+ })
+ return ret, err
+}
+
+// SubmarineClusters returns an object that can list and get SubmarineClusters.
+func (s *submarineClusterLister) SubmarineClusters(namespace string) SubmarineClusterNamespaceLister {
+ return submarineClusterNamespaceLister{indexer: s.indexer, namespace: namespace}
+}
+
+// SubmarineClusterNamespaceLister helps list and get SubmarineClusters.
+type SubmarineClusterNamespaceLister interface {
+ // List lists all SubmarineClusters in the indexer for a given namespace.
+ List(selector labels.Selector) (ret []*v1alpha1.SubmarineCluster, err error)
+ // Get retrieves the SubmarineCluster from the indexer for a given namespace and name.
+ Get(name string) (*v1alpha1.SubmarineCluster, error)
+ SubmarineClusterNamespaceListerExpansion
+}
+
+// submarineClusterNamespaceLister implements the SubmarineClusterNamespaceLister
+// interface.
+type submarineClusterNamespaceLister struct {
+ indexer cache.Indexer
+ namespace string
+}
+
+// List lists all SubmarineClusters in the indexer for a given namespace.
+func (s submarineClusterNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.SubmarineCluster, err error) {
+ err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1alpha1.SubmarineCluster))
+ })
+ return ret, err
+}
+
+// Get retrieves the SubmarineCluster from the indexer for a given namespace and name.
+func (s submarineClusterNamespaceLister) Get(name string) (*v1alpha1.SubmarineCluster, error) {
+ obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
+ if err != nil {
+ return nil, err
+ }
+ if !exists {
+ return nil, errors.NewNotFound(v1alpha1.Resource("submarinecluster"), name)
+ }
+ return obj.(*v1alpha1.SubmarineCluster), nil
+}
diff --git a/submarine-cloud/pkg/client/listers/submarine/v1alpha1/submarineserver.go b/submarine-cloud/pkg/client/listers/submarine/v1alpha1/submarineserver.go
deleted file mode 100644
index 82a7c29..0000000
--- a/submarine-cloud/pkg/client/listers/submarine/v1alpha1/submarineserver.go
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-// Code generated by lister-gen. DO NOT EDIT.
-
-package v1alpha1
-
-import (
- v1alpha1 "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
- "k8s.io/apimachinery/pkg/api/errors"
- "k8s.io/apimachinery/pkg/labels"
- "k8s.io/client-go/tools/cache"
-)
-
-// SubmarineServerLister helps list SubmarineServers.
-type SubmarineServerLister interface {
- // List lists all SubmarineServers in the indexer.
- List(selector labels.Selector) (ret []*v1alpha1.SubmarineServer, err error)
- // SubmarineServers returns an object that can list and get SubmarineServers.
- SubmarineServers(namespace string) SubmarineServerNamespaceLister
- SubmarineServerListerExpansion
-}
-
-// submarineServerLister implements the SubmarineServerLister interface.
-type submarineServerLister struct {
- indexer cache.Indexer
-}
-
-// NewSubmarineServerLister returns a new SubmarineServerLister.
-func NewSubmarineServerLister(indexer cache.Indexer) SubmarineServerLister {
- return &submarineServerLister{indexer: indexer}
-}
-
-// List lists all SubmarineServers in the indexer.
-func (s *submarineServerLister) List(selector labels.Selector) (ret []*v1alpha1.SubmarineServer, err error) {
- err = cache.ListAll(s.indexer, selector, func(m interface{}) {
- ret = append(ret, m.(*v1alpha1.SubmarineServer))
- })
- return ret, err
-}
-
-// SubmarineServers returns an object that can list and get SubmarineServers.
-func (s *submarineServerLister) SubmarineServers(namespace string) SubmarineServerNamespaceLister {
- return submarineServerNamespaceLister{indexer: s.indexer, namespace: namespace}
-}
-
-// SubmarineServerNamespaceLister helps list and get SubmarineServers.
-type SubmarineServerNamespaceLister interface {
- // List lists all SubmarineServers in the indexer for a given namespace.
- List(selector labels.Selector) (ret []*v1alpha1.SubmarineServer, err error)
- // Get retrieves the SubmarineServer from the indexer for a given namespace and name.
- Get(name string) (*v1alpha1.SubmarineServer, error)
- SubmarineServerNamespaceListerExpansion
-}
-
-// submarineServerNamespaceLister implements the SubmarineServerNamespaceLister
-// interface.
-type submarineServerNamespaceLister struct {
- indexer cache.Indexer
- namespace string
-}
-
-// List lists all SubmarineServers in the indexer for a given namespace.
-func (s submarineServerNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.SubmarineServer, err error) {
- err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
- ret = append(ret, m.(*v1alpha1.SubmarineServer))
- })
- return ret, err
-}
-
-// Get retrieves the SubmarineServer from the indexer for a given namespace and name.
-func (s submarineServerNamespaceLister) Get(name string) (*v1alpha1.SubmarineServer, error) {
- obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
- if err != nil {
- return nil, err
- }
- if !exists {
- return nil, errors.NewNotFound(v1alpha1.Resource("submarineserver"), name)
- }
- return obj.(*v1alpha1.SubmarineServer), nil
-}
diff --git a/submarine-cloud/pkg/signals/signal_posix.go b/submarine-cloud/pkg/config/cluster.go
similarity index 63%
rename from submarine-cloud/pkg/signals/signal_posix.go
rename to submarine-cloud/pkg/config/cluster.go
index 78d541f..2f5b6dd 100644
--- a/submarine-cloud/pkg/signals/signal_posix.go
+++ b/submarine-cloud/pkg/config/cluster.go
@@ -15,13 +15,19 @@
* limitations under the License.
*/
-// +build !windows
+package config
-package signals
+import "github.com/spf13/pflag"
-import (
- "os"
- "syscall"
-)
+// Cluster used to store all Submarine Cluster configuration information
+type Cluster struct {
+ Namespace string
+ NodeService string
+}
-var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM}
+// AddFlags use to add the Submarine-Cluster Config flags to the command line
+func (c *Cluster) AddFlags(fs *pflag.FlagSet) {
+ fs.StringVar(&c.Namespace, "ns", "", "Submarine-node k8s namespace")
+ fs.StringVar(&c.NodeService, "rs", "", "Submarine-node k8s service name")
+
+}
diff --git a/submarine-cloud/pkg/config/submarine.go b/submarine-cloud/pkg/config/submarine.go
new file mode 100644
index 0000000..c6acd83
--- /dev/null
+++ b/submarine-cloud/pkg/config/submarine.go
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 config
+
+import (
+ "fmt"
+ "path"
+
+ "github.com/spf13/pflag"
+)
+
+const (
+ // DefaultSubmarineTimeout default Submarine timeout (ms)
+ DefaultSubmarineTimeout = 2000
+ //DefaultClusterNodeTimeout default cluster node timeout (ms)
+ //The maximum amount of time a Submarine Cluster node can be unavailable, without it being considered as failing
+ DefaultClusterNodeTimeout = 2000
+ // SubmarineRenameCommandsDefaultPath default path to volume storing rename commands
+ SubmarineRenameCommandsDefaultPath = "/etc/secret-volume"
+ // SubmarineRenameCommandsDefaultFile default file name containing rename commands
+ SubmarineRenameCommandsDefaultFile = ""
+ // SubmarineConfigFileDefault default config file path
+ SubmarineConfigFileDefault = "/submarine-conf/submarine.conf"
+ // SubmarineServerBinDefault default binary name
+ SubmarineServerBinDefault = "submarine-server"
+ // SubmarineServerPortDefault default Submarine port
+ SubmarineServerPortDefault = "6379"
+ // SubmarineMaxMemoryDefault default Submarine max memory
+ SubmarineMaxMemoryDefault = 0
+ // SubmarineMaxMemoryPolicyDefault default Submarine max memory evition policy
+ SubmarineMaxMemoryPolicyDefault = "noeviction"
+)
+
+// Submarine used to store all Submarine configuration information
+type Submarine struct {
+ DialTimeout int
+ ClusterNodeTimeout int
+ ConfigFileName string
+ renameCommandsPath string
+ renameCommandsFile string
+ HTTPServerAddr string
+ ServerBin string
+ ServerPort string
+ ServerIP string
+ MaxMemory uint32
+ MaxMemoryPolicy string
+ ConfigFiles []string
+}
+
+// AddFlags use to add the Submarine Config flags to the command line
+func (r *Submarine) AddFlags(fs *pflag.FlagSet) {
+ fs.IntVar(&r.DialTimeout, "rdt", DefaultSubmarineTimeout, "Submarine dial timeout (ms)")
+ fs.IntVar(&r.ClusterNodeTimeout, "cluster-node-timeout", DefaultClusterNodeTimeout, "Submarine node timeout (ms)")
+ fs.StringVar(&r.ConfigFileName, "c", SubmarineConfigFileDefault, "Submarine config file path")
+ fs.StringVar(&r.renameCommandsPath, "rename-command-path", SubmarineRenameCommandsDefaultPath, "Path to the folder where rename-commands option for Submarine are available")
+ fs.StringVar(&r.renameCommandsFile, "rename-command-file", SubmarineRenameCommandsDefaultFile, "Name of the file where rename-commands option for Submarine are available, disabled if empty")
+ fs.Uint32Var(&r.MaxMemory, "max-memory", SubmarineMaxMemoryDefault, "Submarine max memory")
+ fs.StringVar(&r.MaxMemoryPolicy, "max-memory-policy", SubmarineMaxMemoryPolicyDefault, "Submarine max memory evition policy")
+ fs.StringVar(&r.ServerBin, "bin", SubmarineServerBinDefault, "Submarine server binary file name")
+ fs.StringVar(&r.ServerPort, "port", SubmarineServerPortDefault, "Submarine server listen port")
+ fs.StringVar(&r.ServerIP, "ip", "", "Submarine server listen ip")
+ fs.StringArrayVar(&r.ConfigFiles, "config-file", []string{}, "Location of Submarine configuration file that will be include in the ")
+
+}
+
+// GetRenameCommandsFile return the path to the rename command file, or empty string if not define
+func (r *Submarine) GetRenameCommandsFile() string {
+ if r.renameCommandsFile == "" {
+ return ""
+ }
+ return path.Join(r.renameCommandsPath, r.renameCommandsFile)
+}
+
+// String stringer interface
+func (r Submarine) String() string {
+ var output string
+ output += fmt.Sprintln("[ Submarine Configuration ]")
+ output += fmt.Sprintln("- DialTimeout:", r.DialTimeout)
+ output += fmt.Sprintln("- ClusterNodeTimeout:", r.ClusterNodeTimeout)
+ output += fmt.Sprintln("- Rename commands:", r.GetRenameCommandsFile())
+ output += fmt.Sprintln("- max-memory:", r.MaxMemory)
+ output += fmt.Sprintln("- max-memory-policy:", r.MaxMemoryPolicy)
+ output += fmt.Sprintln("- server-bin:", r.ServerBin)
+ output += fmt.Sprintln("- server-port:", r.ServerPort)
+ return output
+}
diff --git a/submarine-cloud/pkg/signals/signal_windows.go b/submarine-cloud/pkg/controller/config.go
similarity index 67%
rename from submarine-cloud/pkg/signals/signal_windows.go
rename to submarine-cloud/pkg/controller/config.go
index 08d95fc..786865c 100644
--- a/submarine-cloud/pkg/signals/signal_windows.go
+++ b/submarine-cloud/pkg/controller/config.go
@@ -14,11 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package controller
-package signals
+import "github.com/apache/submarine/submarine-cloud/pkg/config"
-import (
- "os"
-)
+// Config contains the Controller settings
+type Config struct {
+ NbWorker int
+ submarine config.Submarine
+}
-var shutdownSignals = []os.Signal{os.Interrupt}
+// NewConfig builds and returns new Config instance
+func NewConfig(nbWorker int, submarine config.Submarine) *Config {
+ return &Config{
+ NbWorker: nbWorker,
+ submarine: submarine,
+ }
+}
diff --git a/submarine-cloud/pkg/controller/controller.go b/submarine-cloud/pkg/controller/controller.go
new file mode 100644
index 0000000..7cdb0da
--- /dev/null
+++ b/submarine-cloud/pkg/controller/controller.go
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package controller
+
+import (
+ "fmt"
+ "github.com/apache/submarine/submarine-cloud/pkg/controller/pod"
+ "github.com/golang/glog"
+ apiv1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+ "k8s.io/apimachinery/pkg/util/wait"
+ kubeinformers "k8s.io/client-go/informers"
+ "k8s.io/client-go/kubernetes/scheme"
+ typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
+ corev1listers "k8s.io/client-go/listers/core/v1"
+ policyv1listers "k8s.io/client-go/listers/policy/v1beta1"
+ "k8s.io/client-go/tools/cache"
+ "k8s.io/client-go/tools/record"
+ "k8s.io/client-go/util/workqueue"
+ "time"
+
+ rapi "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
+ sClient "github.com/apache/submarine/submarine-cloud/pkg/client/clientset/versioned"
+ sInformers "github.com/apache/submarine/submarine-cloud/pkg/client/informers/externalversions"
+ sListers "github.com/apache/submarine/submarine-cloud/pkg/client/listers/submarine/v1alpha1"
+ clientset "k8s.io/client-go/kubernetes"
+)
+
+// Controller contains all controller fields
+type Controller struct {
+ kubeClient clientset.Interface
+ submarineClient sClient.Interface
+
+ submarineClusterLister sListers.SubmarineClusterLister
+ submarineClusterSynced cache.InformerSynced
+
+ podLister corev1listers.PodLister
+ PodSynced cache.InformerSynced
+
+ serviceLister corev1listers.ServiceLister
+ ServiceSynced cache.InformerSynced
+
+ podDisruptionBudgetLister policyv1listers.PodDisruptionBudgetLister
+ PodDiscruptionBudgetSynced cache.InformerSynced
+
+ podControl pod.SubmarineClusterControlInteface
+ serviceControl ServicesControlInterface
+ podDisruptionBudgetControl PodDisruptionBudgetsControlInterface
+
+ updateHandler func(cluster *rapi.SubmarineCluster) (*rapi.SubmarineCluster, error) // callback to update SubmarineCluster. Added as member for testing
+
+ queue workqueue.RateLimitingInterface // SubmarineClusters to be synced
+ recorder record.EventRecorder
+
+ config *Config
+}
+
+// NewController builds and return new controller instance
+func NewController(cfg *Config, kubeClient clientset.Interface, submarineClient sClient.Interface, kubeInformer kubeinformers.SharedInformerFactory, rInformer sInformers.SharedInformerFactory) *Controller {
+ glog.Info("NewController()")
+ eventBroadcaster := record.NewBroadcaster()
+ eventBroadcaster.StartLogging(glog.Infof)
+ eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeClient.CoreV1().Events("")})
+
+ serviceInformer := kubeInformer.Core().V1().Services()
+ podInformer := kubeInformer.Core().V1().Pods()
+ submarineInformer := rInformer.Submarine().V1alpha1().SubmarineClusters()
+ podDisruptionBudgetInformer := kubeInformer.Policy().V1beta1().PodDisruptionBudgets()
+
+ ctrl := &Controller{
+ kubeClient: kubeClient,
+ submarineClient: submarineClient,
+ submarineClusterLister: submarineInformer.Lister(),
+ submarineClusterSynced: submarineInformer.Informer().HasSynced,
+ podLister: podInformer.Lister(),
+ PodSynced: podInformer.Informer().HasSynced,
+ serviceLister: serviceInformer.Lister(),
+ ServiceSynced: serviceInformer.Informer().HasSynced,
+ podDisruptionBudgetLister: podDisruptionBudgetInformer.Lister(),
+ PodDiscruptionBudgetSynced: podDisruptionBudgetInformer.Informer().HasSynced,
+
+ queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "submarinecluster"),
+ recorder: eventBroadcaster.NewRecorder(scheme.Scheme, apiv1.EventSource{Component: "submarinecluster-controller"}),
+
+ config: cfg,
+ }
+
+ submarineInformer.Informer().AddEventHandler(
+ cache.ResourceEventHandlerFuncs{
+ AddFunc: ctrl.onAddSubmarineCluster,
+ UpdateFunc: ctrl.onUpdateSubmarineCluster,
+ DeleteFunc: ctrl.onDeleteSubmarineCluster,
+ },
+ )
+
+ podInformer.Informer().AddEventHandler(
+ cache.ResourceEventHandlerFuncs{
+ AddFunc: ctrl.onAddPod,
+ UpdateFunc: ctrl.onUpdatePod,
+ DeleteFunc: ctrl.onDeletePod,
+ },
+ )
+
+ ctrl.updateHandler = ctrl.updateSubmarineCluster
+ ctrl.podControl = pod.NewSubmarineClusterControl(ctrl.podLister, ctrl.kubeClient, ctrl.recorder)
+ ctrl.serviceControl = NewServicesControl(ctrl.kubeClient, ctrl.recorder)
+ ctrl.podDisruptionBudgetControl = NewPodDisruptionBudgetsControl(ctrl.kubeClient, ctrl.recorder)
+
+ return ctrl
+}
+
+// Run executes the Controller
+func (c *Controller) Run(stop <-chan struct{}) error {
+ glog.Infof("Starting SubmarineCluster controller")
+
+ if !cache.WaitForCacheSync(stop, c.PodSynced, c.submarineClusterSynced, c.ServiceSynced) {
+ return fmt.Errorf("Timed out waiting for caches to sync")
+ }
+
+ for i := 0; i < c.config.NbWorker; i++ {
+ go wait.Until(c.runWorker, time.Second, stop)
+ }
+
+ <-stop
+ return nil
+}
+
+func (c *Controller) runWorker() {
+ for c.processNextItem() {
+ }
+}
+
+func (c *Controller) processNextItem() bool {
+ key, quit := c.queue.Get()
+ if quit {
+ return false
+ }
+ defer c.queue.Done(key)
+ needRequeue, err := c.sync(key.(string))
+ if err == nil {
+ c.queue.Forget(key)
+ } else {
+ utilruntime.HandleError(fmt.Errorf("Error syncing submarinecluster: %v", err))
+ c.queue.AddRateLimited(key)
+ return true
+ }
+
+ if needRequeue {
+ glog.V(4).Info("processNextItem: Requeue key:", key)
+ c.queue.AddRateLimited(key)
+ }
+
+ return true
+}
+
+func (c *Controller) sync(key string) (bool, error) {
+ glog.V(2).Infof("sync() key:%s", key)
+ startTime := metav1.Now()
+ defer func() {
+ glog.V(2).Infof("Finished syncing SubmarineCluster %q (%v", key, time.Since(startTime.Time))
+ }()
+ namespace, name, err := cache.SplitMetaNamespaceKey(key)
+ if err != nil {
+ return false, err
+ }
+ glog.V(6).Infof("Syncing %s/%s", namespace, name)
+ sharedSubmarineCluster, err := c.submarineClusterLister.SubmarineClusters(namespace).Get(name)
+ if err != nil {
+ glog.Errorf("unable to get SubmarineCluster %s/%s: %v. Maybe deleted", namespace, name, err)
+ return false, nil
+ }
+
+ if !rapi.IsDefaultedSubmarineCluster(sharedSubmarineCluster) {
+ defaultedSubmarineCluster := rapi.DefaultSubmarineCluster(sharedSubmarineCluster)
+ if _, err = c.updateHandler(defaultedSubmarineCluster); err != nil {
+ glog.Errorf("SubmarineCluster %s/%s updated error:, err", namespace, name)
+ return false, fmt.Errorf("unable to default SubmarineCluster %s/%s: %v", namespace, name, err)
+ }
+ glog.V(6).Infof("SubmarineCluster-Operator.sync Defaulted %s/%s", namespace, name)
+ return false, nil
+ }
+
+ // TODO add validation
+
+ // TODO: add test the case of graceful deletion
+ if sharedSubmarineCluster.DeletionTimestamp != nil {
+ return false, nil
+ }
+
+ submarinecluster := sharedSubmarineCluster.DeepCopy()
+
+ // Init status.StartTime
+ if submarinecluster.Status.StartTime == nil {
+ submarinecluster.Status.StartTime = &startTime
+ if _, err := c.updateHandler(submarinecluster); err != nil {
+ glog.Errorf("SubmarineCluster %s/%s: unable init startTime: %v", namespace, name, err)
+ return false, nil
+ }
+ glog.V(4).Infof("SubmarineCluster %s/%s: startTime updated", namespace, name)
+ return false, nil
+ }
+ return c.syncCluster(submarinecluster)
+}
+
+func (c *Controller) syncCluster(submarineCluster *rapi.SubmarineCluster) (forceRequeue bool, err error) {
+ glog.Infof("syncCluster()")
+ return false, nil
+}
+
+func (c *Controller) onAddSubmarineCluster(obj interface{}) {
+ glog.Infof("onAddSubmarineCluster(%v)", obj)
+}
+
+func (c *Controller) onDeleteSubmarineCluster(obj interface{}) {
+ glog.Infof("onDeleteSubmarineCluster(%v)", obj)
+}
+
+func (c *Controller) onUpdateSubmarineCluster(oldObj, newObj interface{}) {
+ glog.Infof("onUpdateSubmarineCluster(%v, %v)", oldObj, newObj)
+}
+
+func (c *Controller) onAddPod(obj interface{}) {
+ glog.Infof("onAddPod(%v)", obj)
+}
+
+func (c *Controller) onUpdatePod(oldObj, newObj interface{}) {
+ glog.Infof("onUpdatePod()")
+}
+
+func (c *Controller) onDeletePod(obj interface{}) {
+ glog.Infof("onDeletePod()")
+}
+
+func (c *Controller) updateSubmarineCluster(submarineCluster *rapi.SubmarineCluster) (*rapi.SubmarineCluster, error) {
+ rc, err := c.submarineClient.SubmarineV1alpha1().SubmarineClusters(submarineCluster.Namespace).Update(submarineCluster)
+ if err != nil {
+ glog.Errorf("updateSubmarineCluster cluster: [%v] error: %v", *submarineCluster, err)
+ return rc, err
+ }
+
+ glog.V(6).Infof("SubmarineCluster %s/%s updated", submarineCluster.Namespace, submarineCluster.Name)
+ return rc, nil
+}
diff --git a/submarine-cloud/pkg/controller/pod/control.go b/submarine-cloud/pkg/controller/pod/control.go
new file mode 100644
index 0000000..a3ab1b7
--- /dev/null
+++ b/submarine-cloud/pkg/controller/pod/control.go
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 pod
+
+import (
+ rapi "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
+ "github.com/golang/glog"
+ kapiv1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ clientset "k8s.io/client-go/kubernetes"
+ corev1listers "k8s.io/client-go/listers/core/v1"
+ "k8s.io/client-go/tools/record"
+)
+
+// SubmarineClusterControlInteface interface for the SubmarineClusterPodControl
+type SubmarineClusterControlInteface interface {
+ // GetSubmarineClusterPods return list of Pod attached to a SubmarineCluster
+ GetSubmarineClusterPods(submarineCluster *rapi.SubmarineCluster) ([]*kapiv1.Pod, error)
+ // CreatePod used to create a Pod from the SubmarineCluster pod template
+ CreatePod(submarineCluster *rapi.SubmarineCluster) (*kapiv1.Pod, error)
+ // DeletePod used to delete a pod from its name
+ DeletePod(submarineCluster *rapi.SubmarineCluster, podName string) error
+ // DeletePodNow used to delete now (force) a pod from its name
+ DeletePodNow(submarineCluster *rapi.SubmarineCluster, podName string) error
+}
+
+// SubmarineClusterControl contains requieres accessor to managing the SubmarineCluster pods
+type SubmarineClusterControl struct {
+ PodLister corev1listers.PodLister
+ KubeClient clientset.Interface
+ Recorder record.EventRecorder
+}
+
+// NewSubmarineClusterControl builds and returns new NewSubmarineClusterControl instance
+func NewSubmarineClusterControl(lister corev1listers.PodLister, client clientset.Interface, rec record.EventRecorder) *SubmarineClusterControl {
+ glog.Infof("NewSubmarineClusterControl()")
+ ctrl := &SubmarineClusterControl{
+ PodLister: lister,
+ KubeClient: client,
+ Recorder: rec,
+ }
+ return ctrl
+}
+
+// GetSubmarineClusterPods return list of Pod attached to a SubmarineCluster
+func (p *SubmarineClusterControl) GetSubmarineClusterPods(submarineCluster *rapi.SubmarineCluster) ([]*kapiv1.Pod, error) {
+ glog.Infof("GetSubmarineClusterPods()")
+ return nil, nil
+}
+
+// CreatePod used to create a Pod from the SubmarineCluster pod template
+func (p *SubmarineClusterControl) CreatePod(submarineCluster *rapi.SubmarineCluster) (*kapiv1.Pod, error) {
+ glog.Infof("CreatePod()")
+ return nil, nil
+}
+
+// DeletePod used to delete a pod from its name
+func (p *SubmarineClusterControl) DeletePod(submarineCluster *rapi.SubmarineCluster, podName string) error {
+ glog.V(6).Infof("DeletePod: %s/%s", submarineCluster.Namespace, podName)
+ return p.deletePodGracefullperiode(submarineCluster, podName, nil)
+}
+
+// DeletePodNow used to delete now (force) a pod from its name
+func (p *SubmarineClusterControl) DeletePodNow(submarineCluster *rapi.SubmarineCluster, podName string) error {
+ glog.V(6).Infof("DeletePod: %s/%s", submarineCluster.Namespace, podName)
+ now := int64(0)
+ return p.deletePodGracefullperiode(submarineCluster, podName, &now)
+}
+
+// DeletePodNow used to delete now (force) a pod from its name
+func (p *SubmarineClusterControl) deletePodGracefullperiode(submarineCluster *rapi.SubmarineCluster, podName string, period *int64) error {
+ glog.Infof("deletePodGracefullperiode()")
+ return p.KubeClient.CoreV1().Pods(submarineCluster.Namespace).Delete(podName, &metav1.DeleteOptions{GracePeriodSeconds: period})
+}
diff --git a/submarine-cloud/pkg/controller/poddisruptionbudgets_control.go b/submarine-cloud/pkg/controller/poddisruptionbudgets_control.go
new file mode 100644
index 0000000..3b283ae
--- /dev/null
+++ b/submarine-cloud/pkg/controller/poddisruptionbudgets_control.go
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 (
+ rapi "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
+ policyv1 "k8s.io/api/policy/v1beta1"
+ clientset "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/tools/record"
+)
+
+// PodDisruptionBudgetsControlInterface inferface for the PodDisruptionBudgetsControl
+type PodDisruptionBudgetsControlInterface interface {
+ // CreateSubmarineClusterPodDisruptionBudget used to create the Kubernetes PodDisruptionBudget needed to access the Submarine Cluster
+ CreateSubmarineClusterPodDisruptionBudget(submarineCluster *rapi.SubmarineCluster) (*policyv1.PodDisruptionBudget, error)
+ // DeleteSubmarineClusterPodDisruptionBudget used to delete the Kubernetes PodDisruptionBudget linked to the Submarine Cluster
+ DeleteSubmarineClusterPodDisruptionBudget(submarineCluster *rapi.SubmarineCluster) error
+ // GetSubmarineClusterPodDisruptionBudget used to retrieve the Kubernetes PodDisruptionBudget associated to the SubmarineCluster
+ GetSubmarineClusterPodDisruptionBudget(submarineCluster *rapi.SubmarineCluster) (*policyv1.PodDisruptionBudget, error)
+}
+
+// PodDisruptionBudgetsControl contains all information for managing Kube PodDisruptionBudgets
+type PodDisruptionBudgetsControl struct {
+ KubeClient clientset.Interface
+ Recorder record.EventRecorder
+}
+
+// NewPodDisruptionBudgetsControl builds and returns new PodDisruptionBudgetsControl instance
+func NewPodDisruptionBudgetsControl(client clientset.Interface, rec record.EventRecorder) *PodDisruptionBudgetsControl {
+ ctrl := &PodDisruptionBudgetsControl{
+ KubeClient: client,
+ Recorder: rec,
+ }
+
+ return ctrl
+}
+
+// GetSubmarineClusterPodDisruptionBudget used to retrieve the Kubernetes PodDisruptionBudget associated to the SubmarineCluster
+func (s *PodDisruptionBudgetsControl) GetSubmarineClusterPodDisruptionBudget(submarineCluster *rapi.SubmarineCluster) (*policyv1.PodDisruptionBudget, error) {
+ return nil, nil
+}
+
+// DeleteSubmarineClusterPodDisruptionBudget used to delete the Kubernetes PodDisruptionBudget linked to the Submarine Cluster
+func (s *PodDisruptionBudgetsControl) DeleteSubmarineClusterPodDisruptionBudget(submarineCluster *rapi.SubmarineCluster) error {
+ return nil
+}
+
+// CreateSubmarineClusterPodDisruptionBudget used to create the Kubernetes PodDisruptionBudget needed to access the Submarine Cluster
+func (s *PodDisruptionBudgetsControl) CreateSubmarineClusterPodDisruptionBudget(submarineCluster *rapi.SubmarineCluster) (*policyv1.PodDisruptionBudget, error) {
+
+ return nil, nil
+}
diff --git a/submarine-cloud/pkg/controller/services_control.go b/submarine-cloud/pkg/controller/services_control.go
new file mode 100644
index 0000000..7137995
--- /dev/null
+++ b/submarine-cloud/pkg/controller/services_control.go
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 (
+ rapi "github.com/apache/submarine/submarine-cloud/pkg/apis/submarine/v1alpha1"
+ "github.com/golang/glog"
+ kapiv1 "k8s.io/api/core/v1"
+ clientset "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/tools/record"
+)
+
+// ServicesControlInterface inferface for the ServicesControl
+type ServicesControlInterface interface {
+ // CreateSubmarineClusterService used to create the Kubernetes Service needed to access the Submarine Cluster
+ CreateSubmarineClusterService(submarineCluster *rapi.SubmarineCluster) (*kapiv1.Service, error)
+ // DeleteSubmarineClusterService used to delete the Kubernetes Service linked to the Submarine Cluster
+ DeleteSubmarineClusterService(submarineCluster *rapi.SubmarineCluster) error
+ // GetSubmarineClusterService used to retrieve the Kubernetes Service associated to the SubmarineCluster
+ GetSubmarineClusterService(submarineCluster *rapi.SubmarineCluster) (*kapiv1.Service, error)
+}
+
+// ServicesControl contains all information for managing Kube Services
+type ServicesControl struct {
+ KubeClient clientset.Interface
+ Recorder record.EventRecorder
+}
+
+// NewServicesControl builds and returns new ServicesControl instance
+func NewServicesControl(client clientset.Interface, rec record.EventRecorder) *ServicesControl {
+ glog.Infof("NewServicesControl()")
+ ctrl := &ServicesControl{
+ KubeClient: client,
+ Recorder: rec,
+ }
+
+ return ctrl
+}
+
+// GetSubmarineClusterService used to retrieve the Kubernetes Service associated to the SubmarineCluster
+func (s *ServicesControl) GetSubmarineClusterService(submarineCluster *rapi.SubmarineCluster) (*kapiv1.Service, error) {
+ glog.Infof("GetSubmarineClusterService()")
+ return nil, nil
+}
+
+// CreateSubmarineClusterService used to create the Kubernetes Service needed to access the Submarine Cluster
+func (s *ServicesControl) CreateSubmarineClusterService(submarineCluster *rapi.SubmarineCluster) (*kapiv1.Service, error) {
+ glog.Infof("CreateSubmarineClusterService()")
+ return nil, nil
+}
+
+// DeleteSubmarineClusterService used to delete the Kubernetes Service linked to the Submarine Cluster
+func (s *ServicesControl) DeleteSubmarineClusterService(submarineCluster *rapi.SubmarineCluster) error {
+ glog.Infof("DeleteSubmarineClusterService()")
+ return nil
+}
diff --git a/submarine-cloud/pkg/operator/config.go b/submarine-cloud/pkg/operator/config.go
new file mode 100644
index 0000000..eaa01ce
--- /dev/null
+++ b/submarine-cloud/pkg/operator/config.go
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 operator
+
+import (
+ "github.com/apache/submarine/submarine-cloud/pkg/config"
+ "github.com/spf13/pflag"
+)
+
+// Config contains configuration for submarine-operator
+type Config struct {
+ KubeConfigFile string
+ Master string
+ ListenAddr string
+ Submarine config.Submarine
+}
+
+// NewSubmarineOperatorConfig builds and returns a submarine-operator Config
+func NewSubmarineOperatorConfig() *Config {
+ return &Config{}
+}
+
+// AddFlags add cobra flags to populate Config
+func (c *Config) AddFlags(fs *pflag.FlagSet) {
+ fs.StringVar(&c.KubeConfigFile, "kubeconfig", c.KubeConfigFile, "Location of kubecfg file for access to kubernetes master service")
+ fs.StringVar(&c.Master, "master", c.Master, "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
+ fs.StringVar(&c.ListenAddr, "addr", "0.0.0.0:8086", "listen address of the http server which serves kubernetes probes and prometheus endpoints")
+ c.Submarine.AddFlags(fs)
+}
diff --git a/submarine-cloud/pkg/operator/operator.go b/submarine-cloud/pkg/operator/operator.go
new file mode 100644
index 0000000..dff37cc
--- /dev/null
+++ b/submarine-cloud/pkg/operator/operator.go
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 operator
+
+import (
+ "github.com/apache/submarine/submarine-cloud/pkg/client"
+ "github.com/apache/submarine/submarine-cloud/pkg/controller"
+ apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
+ "k8s.io/client-go/rest"
+ "k8s.io/client-go/tools/clientcmd"
+ "time"
+
+ submarineInformers "github.com/apache/submarine/submarine-cloud/pkg/client/informers/externalversions"
+ kubeinformers "k8s.io/client-go/informers"
+ clientset "k8s.io/client-go/kubernetes"
+
+ "github.com/golang/glog"
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
+)
+
+// Controller is the controller implementation for Student resources
+type SubmarineOperator struct {
+ kubeInformerFactory kubeinformers.SharedInformerFactory
+ submarineInformerFactory submarineInformers.SharedInformerFactory
+ controller *controller.Controller
+}
+
+func NewSubmarineOperator(cfg *Config) *SubmarineOperator {
+ kubeConfig, err := initKubeConfig(cfg)
+ if err != nil {
+ glog.Fatalf("Unable to init submarinecluster controller: %v", err)
+ }
+
+ extClient, err := apiextensionsclient.NewForConfig(kubeConfig)
+ if err != nil {
+ glog.Fatalf("Unable to init submarinClientset from kubeconfig:%v", err)
+ }
+ _, err = client.DefineSubmarineClusterResource(extClient)
+ if err != nil && !apierrors.IsAlreadyExists(err) {
+ glog.Fatalf("Unable to define SubmarineCluster resource:%v", err)
+ }
+
+ kubeClient, err := clientset.NewForConfig(kubeConfig)
+ if err != nil {
+ glog.Fatalf("Unable to initialize kubeClient:%v", err)
+ }
+
+ submarineClient, err := client.NewClient(kubeConfig)
+ if err != nil {
+ glog.Fatalf("Unable to init submarine.submarinClientset from kubeconfig:%v", err)
+ }
+
+ kubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, time.Second*30)
+ submarineInformerFactory := submarineInformers.NewSharedInformerFactory(submarineClient, time.Second*30)
+ op := &SubmarineOperator{
+ kubeInformerFactory: kubeInformerFactory,
+ submarineInformerFactory: submarineInformerFactory,
+ controller: controller.NewController(controller.NewConfig(1, cfg.Submarine), kubeClient, submarineClient, kubeInformerFactory, submarineInformerFactory),
+ }
+
+ return op
+}
+
+func initKubeConfig(c *Config) (*rest.Config, error) {
+ if len(c.KubeConfigFile) > 0 {
+ return clientcmd.BuildConfigFromFlags(c.Master, c.KubeConfigFile) // out of cluster config
+ }
+ return rest.InClusterConfig()
+}
+
+// Run executes the Submarine Operator
+func (op *SubmarineOperator) Run(stop <-chan struct{}) error {
+ var err error
+ if op.controller != nil {
+ op.kubeInformerFactory.Start(stop)
+ op.submarineInformerFactory.Start(stop)
+ err = op.controller.Run(stop)
+ }
+
+ return err
+}
diff --git a/submarine-cloud/pkg/signals/signal.go b/submarine-cloud/pkg/signal/signal.go
similarity index 66%
rename from submarine-cloud/pkg/signals/signal.go
rename to submarine-cloud/pkg/signal/signal.go
index 7e1a6b4..c494127 100644
--- a/submarine-cloud/pkg/signals/signal.go
+++ b/submarine-cloud/pkg/signal/signal.go
@@ -14,28 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package signals
+package signal
import (
+ "context"
"os"
"os/signal"
-)
-
-var onlyOneSignalHandler = make(chan struct{})
+ "syscall"
-func SetupSignalHandler() (stopCh <-chan struct{}) {
- close(onlyOneSignalHandler) // panics when called twice
-
- stop := make(chan struct{})
- c := make(chan os.Signal, 2)
- signal.Notify(c, shutdownSignals...)
- go func() {
- <-c
- close(stop)
- <-c
- os.Exit(1) // second signal. Exit directly.
- }()
+ "github.com/golang/glog"
+)
- return stop
+// HandleSignal used to listen several os signal and then execute the cancel function
+func HandleSignal(cancelFunc context.CancelFunc) {
+ sigc := make(chan os.Signal, 1)
+ signal.Notify(sigc,
+ syscall.SIGHUP,
+ syscall.SIGINT,
+ syscall.SIGTERM,
+ syscall.SIGQUIT)
+ sig := <-sigc
+ glog.Infof("Signal received: %s, stop the process", sig.String())
+ cancelFunc()
}
diff --git a/submarine-cloud/pkg/utils/build.go b/submarine-cloud/pkg/utils/build.go
new file mode 100644
index 0000000..ebcb876
--- /dev/null
+++ b/submarine-cloud/pkg/utils/build.go
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 utils
+
+import (
+ "fmt"
+ "time"
+)
+
+// BUILDTIME should be populated by at build time: -ldflags "-w -X github.com/apache/submarine/submarine-cloud/pkg/utils.BUILDTIME=${DATE}
+// with for example DATE=$(shell date +%Y-%m-%d/%H:%M:%S ) (pay attention not to use space!)
+var BUILDTIME string
+
+// TAG should be populated by at build time: -ldflags "-w -X github.com/apache/submarine/submarine-cloud/pkg/utils.TAG=${TAG}
+// with for example TAG=$(shell git tag|tail -1)
+var TAG string
+
+// COMMIT should be populated by at build time: -ldflags "-w -X github.com/apache/submarine/submarine-cloud/pkg/utils.COMMIT=${COMMIT}
+// with for example COMMIT=$(shell git rev-parse HEAD)
+var COMMIT string
+
+// VERSION should be populated by at build time: -ldflags "-w -X github.com/apache/submarine/submarine-cloud/pkg/utils.VERSION=${VERSION}
+// with for example VERSION=$(shell git rev-parse --abbrev-ref HEAD)
+var VERSION string
+
+// BuildInfos returns builds information
+func BuildInfos() {
+ fmt.Println("Program started at: " + time.Now().String())
+ fmt.Println("BUILDTIME=" + BUILDTIME)
+ fmt.Println("TAG=" + TAG)
+ fmt.Println("COMMIT=" + COMMIT)
+ fmt.Println("VERSION=" + VERSION)
+}
diff --git a/submarine-cloud/submarine-operator.md b/submarine-cloud/submarine-operator.md
index 022f6b6..a785222 100644
--- a/submarine-cloud/submarine-operator.md
+++ b/submarine-cloud/submarine-operator.md
@@ -45,6 +45,7 @@ Mainly prepare the declaration and registration interface of the resource object
```
go get -u k8s.io/apimachinery/pkg/apis/meta/v1
go get -u k8s.io/code-generator/...
+go get -u k8s.io/apiextensions-apiserver/...
```
## 3. Automatically generate Client, Informer, WorkQueue related code
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@submarine.apache.org
For additional commands, e-mail: dev-help@submarine.apache.org