func startKontrol(pem, pub string, port int) (*Kontrol, *Config) { conf := config.New() conf.Username = "******" conf.KontrolURL = fmt.Sprintf("http://localhost:%d/kite", port) conf.KontrolKey = pub conf.KontrolUser = "******" conf.KiteKey = testutil.NewToken("testuser", pem, pub).Raw conf.ReadEnvironmentVariables() DefaultPort = port kon := New(conf.Copy(), "1.0.0") // kon.Kite.SetLogLevel(kite.DEBUG) switch os.Getenv("KONTROL_STORAGE") { case "etcd": kon.SetStorage(NewEtcd(nil, kon.Kite.Log)) case "postgres": p := NewPostgres(nil, kon.Kite.Log) kon.SetStorage(p) kon.SetKeyPairStorage(p) default: kon.SetStorage(NewEtcd(nil, kon.Kite.Log)) } kon.AddKeyPair("", pub, pem) go kon.Run() <-kon.Kite.ServerReadyNotify() return kon, &Config{ Config: conf, Private: pem, Public: pub, } }
func init() { conf = config.New() conf.Username = "******" conf.KontrolURL = "http://localhost:4099/kite" conf.KontrolKey = testkeys.Public conf.KontrolUser = "******" conf.KiteKey = testutil.NewKiteKey().Raw conf.ReadEnvironmentVariables() kontrol.DefaultPort = 4099 kon := kontrol.New(conf.Copy(), "0.1.0") switch os.Getenv("KONTROL_STORAGE") { case "etcd": kon.SetStorage(kontrol.NewEtcd(nil, kon.Kite.Log)) case "postgres": p := kontrol.NewPostgres(nil, kon.Kite.Log) kon.SetStorage(p) kon.SetKeyPairStorage(p) default: kon.SetStorage(kontrol.NewEtcd(nil, kon.Kite.Log)) } kon.AddKeyPair("", testkeys.Public, testkeys.Private) go kon.Run() <-kon.Kite.ServerReadyNotify() }
func NewConfig() *config.Config { conf := config.New() conf.Username = "******" conf.KontrolURL = "http://localhost:4000/kite" conf.KontrolKey = testkeys.Public conf.KontrolUser = "******" conf.KiteKey = NewKiteKey().Raw return conf }
func initialKey(kontrolConf *Kontrol, publicKey, privateKey []byte) { conf := config.New() if kontrolConf.Username == "" { log.Fatalln("empty username") } conf.Username = kontrolConf.Username _, err := url.Parse(kontrolConf.KontrolURL) if err != nil { log.Fatalln("cannot parse kontrol URL") } conf.KontrolURL = kontrolConf.KontrolURL k := kontrol.New(conf, kontrolConf.Version) k.AddKeyPair("", string(publicKey), string(privateKey)) err = k.InitializeSelf() if err != nil { log.Fatal(err) } fmt.Println("kite.key is written to ~/.kite/kite.key. You can see it with:\n\tkitectl showkey") }
func (k *Konfig) buildKiteConfig() *konfig.Config { if k.KiteKey != "" { tok, err := jwt.ParseWithClaims(k.KiteKey, &kitekey.KiteClaims{}, kitekey.GetKontrolKey) if err == nil { cfg := &konfig.Config{} if err = cfg.ReadToken(tok); err == nil { return cfg } } } if k.KiteKeyFile != "" { if cfg, err := konfig.NewFromKiteKey(k.KiteKeyFile); err == nil { return cfg } } if cfg, err := konfig.Get(); err == nil { return cfg } return konfig.New() }
// New creates, initialize and then returns a new Kite instance. Version must // be in 3-digit semantic form. Name is important that it's also used to be // searched by others. func New(name, version string) *Kite { if name == "" { panic("kite: name cannot be empty") } if digits := strings.Split(version, "."); len(digits) != 3 { panic("kite: version must be 3-digits semantic version") } kiteID, err := uuid.NewV4() if err != nil { panic(fmt.Sprintf("kite: cannot generate unique ID: %s", err.Error())) } l, setlevel := newLogger(name) kClient := &kontrolClient{ readyConnected: make(chan struct{}), readyRegistered: make(chan struct{}), registerChan: make(chan *url.URL, 1), } k := &Kite{ Config: config.New(), Log: l, SetLogLevel: setlevel, Authenticators: make(map[string]func(*Request) error), trustedKontrolKeys: make(map[string]string), handlers: make(map[string]*Method), preHandlers: make([]Handler, 0), postHandlers: make([]Handler, 0), kontrol: kClient, name: name, version: version, Id: kiteID.String(), readyC: make(chan bool), closeC: make(chan bool), muxer: mux.NewRouter(), } // We change the heartbeat interval from 25 seconds to 10 seconds. This is // better for environments such as AWS ELB. sockjsOpts := sockjs.DefaultOptions sockjsOpts.HeartbeatDelay = 10 * time.Second // All sockjs communication is done through this endpoint.. k.muxer.PathPrefix("/kite").Handler(sockjs.NewHandler("/kite", sockjsOpts, k.sockjsHandler)) // Add useful debug logs k.OnConnect(func(c *Client) { k.Log.Debug("New session: %s", c.session.ID()) }) k.OnFirstRequest(func(c *Client) { k.Log.Debug("Session %q is identified as %q", c.session.ID(), c.Kite) }) k.OnDisconnect(func(c *Client) { k.Log.Debug("Kite has disconnected: %q", c.Kite) }) // Every kite should be able to authenticate the user from token. // Tokens are granted by Kontrol Kite. k.Authenticators["token"] = k.AuthenticateFromToken // A kite accepts requests with the same username. k.Authenticators["kiteKey"] = k.AuthenticateFromKiteKey // Register default methods and handlers. k.addDefaultHandlers() return k }
func TestProxy(t *testing.T) { conf := config.New() conf.Username = "******" conf.KontrolURL = "ws://localhost:6666/kite" conf.KontrolKey = testkeys.Public conf.KontrolUser = "******" conf.KiteKey = testutil.NewKiteKey().Raw conf.Transport = config.WebSocket // tunnel only works via WebSocket // start kontrol color.Green("Starting kontrol") kontrol.DefaultPort = 6666 kon := kontrol.New(conf.Copy(), "0.1.0") switch os.Getenv("KONTROL_STORAGE") { case "etcd": kon.SetStorage(kontrol.NewEtcd(nil, kon.Kite.Log)) case "postgres": p := kontrol.NewPostgres(nil, kon.Kite.Log) kon.SetStorage(p) kon.SetKeyPairStorage(p) default: kon.SetStorage(kontrol.NewEtcd(nil, kon.Kite.Log)) } kon.AddKeyPair("", testkeys.Public, testkeys.Private) go kon.Run() <-kon.Kite.ServerReadyNotify() DefaultPort = 4999 DefaultPublicHost = "localhost:4999" prxConf := conf.Copy() prxConf.DisableAuthentication = true // no kontrol running in test prx := New(prxConf, "0.1.0", testkeys.Public, testkeys.Private) prx.Start() log.Println("Proxy started") // Proxy kite is ready. kite1 := kite.New("kite1", "1.0.0") kite1.Config = conf.Copy() kite1.HandleFunc("foo", func(r *kite.Request) (interface{}, error) { return "bar", nil }) prxClt := kite1.NewClient("http://localhost:4999/kite") err := prxClt.Dial() if err != nil { t.Fatal(err) } // Kite1 is connected to proxy. result, err := prxClt.TellWithTimeout("register", 4*time.Second) if err != nil { t.Fatal(err) } proxyURL := result.MustString() log.Printf("Registered to proxy with URL: %s", proxyURL) if !strings.Contains(proxyURL, "/proxy") { t.Fatalf("Invalid proxy URL: %s", proxyURL) } kite2 := kite.New("kite2", "1.0.0") kite2.Config = conf.Copy() kite1remote := kite2.NewClient(proxyURL) err = kite1remote.Dial() if err != nil { t.Fatal(err) } // kite2 is connected to kite1 via proxy kite. result, err = kite1remote.TellWithTimeout("foo", 4*time.Second) if err != nil { t.Fatal(err) } s := result.MustString() if s != "bar" { t.Fatalf("Wrong reply: %s", s) } }
func TestWebSocketProxy(t *testing.T) { color.Blue("====> Starting WebSocket test") conf := config.New() conf.Username = "******" conf.KontrolURL = "http://localhost:5555/kite" conf.KontrolKey = testkeys.Public conf.KontrolUser = "******" conf.KiteKey = testutil.NewKiteKey().Raw conf.ReadEnvironmentVariables() // start kontrol color.Green("Starting kontrol") kontrol.DefaultPort = 5555 kon := kontrol.New(conf.Copy(), "0.1.0") switch os.Getenv("KONTROL_STORAGE") { case "etcd": kon.SetStorage(kontrol.NewEtcd(nil, kon.Kite.Log)) case "postgres": p := kontrol.NewPostgres(nil, kon.Kite.Log) kon.SetStorage(p) kon.SetKeyPairStorage(p) default: kon.SetStorage(kontrol.NewEtcd(nil, kon.Kite.Log)) } kon.AddKeyPair("", testkeys.Public, testkeys.Private) go kon.Run() <-kon.Kite.ServerReadyNotify() // start proxy color.Green("Starting Proxy and registering to Kontrol") proxyConf := conf.Copy() proxyConf.Port = 4999 proxy := New(proxyConf) proxy.PublicHost = "localhost" proxy.PublicPort = proxyConf.Port proxy.Scheme = "http" go proxy.Run() <-proxy.ReadyNotify() proxyRegisterURL := &url.URL{ Scheme: proxy.Scheme, Host: proxy.PublicHost + ":" + strconv.Itoa(proxy.PublicPort), Path: "/kite", } fmt.Printf("proxyRegisterURL %+v\n", proxyRegisterURL) _, err := proxy.Kite.Register(proxyRegisterURL) if err != nil { t.Error(err) } // start now backend kite color.Green("Starting BackendKite") backendKite := kite.New("backendKite", "1.0.0") backendKite.Config = conf.Copy() backendKite.HandleFunc("foo", func(r *kite.Request) (interface{}, error) { return "bar", nil }) backendKite.Config.Port = 7777 kiteUrl := &url.URL{Scheme: "http", Host: "localhost:7777", Path: "/kite"} go backendKite.Run() <-backendKite.ServerReadyNotify() // now search for a proxy from kontrol color.Green("BackendKite is searching proxy from kontrol") kites, err := backendKite.GetKites(&protocol.KontrolQuery{ Username: "******", Environment: config.DefaultConfig.Environment, Name: Name, }) if err != nil { t.Fatal(err) } proxyKite := kites[0] err = proxyKite.Dial() if err != nil { t.Fatal(err) } // backendKite is connected to proxy, now let us register to proxy and get // a proxy url. We send our url to proxy, it needs it in order to proxy us color.Green("Backendkite found proxy, now registering to it") result, err := proxyKite.TellWithTimeout("register", 4*time.Second, kiteUrl.String()) if err != nil { t.Fatal(err) } proxyURL := result.MustString() if !strings.Contains(proxyURL, "/proxy") { t.Fatalf("Invalid proxy URL: %s", proxyURL) } registerURL, err := url.Parse(proxyURL) if err != nil { t.Fatal(err) } // register ourself to kontrol with this proxyUrl color.Green("BackendKite is registering to Kontrol with the result from proxy") go backendKite.RegisterForever(registerURL) <-backendKite.KontrolReadyNotify() // now another completely foreign kite and will search for our backend // kite, connect to it and execute the "foo" method color.Green("Foreign kite started") foreignKite := kite.New("foreignKite", "1.0.0") foreignKite.Config = conf.Copy() color.Green("Querying backendKite now") backendKites, err := foreignKite.GetKites(&protocol.KontrolQuery{ Username: "******", Environment: config.DefaultConfig.Environment, Name: "backendKite", }) remoteBackendKite := backendKites[0] color.Green("Dialing BackendKite") err = remoteBackendKite.Dial() if err != nil { t.Fatal(err) } // foreignKite is connected to backendKite via proxy kite, fire our call... color.Green("Calling BackendKite's foo method") result, err = remoteBackendKite.TellWithTimeout("foo", 4*time.Second) if err != nil { t.Fatal(err) } s := result.MustString() if s != "bar" { t.Fatalf("Wrong reply: %s", s) } }
func init() { if s := os.Getenv("KLOUD_TEST_REGION"); s != "" { team.Region = s } if s := os.Getenv("KLOUD_TEST_INSTANCE_TYPE"); s != "" { team.InstanceType = s } repoPath, err := currentRepoPath() if err != nil { log.Fatal("currentRepoPath error:", err) } conf = config.New() conf.Username = "******" conf.KontrolURL = os.Getenv("KLOUD_KONTROL_URL") if conf.KontrolURL == "" { conf.KontrolURL = "http://localhost:4099/kite" } conf.KontrolKey = testkeys.Public conf.KontrolUser = "******" conf.KiteKey = testutil.NewKiteKey().Raw // Power up our own kontrol kite for self-contained tests log.Println("Starting Kontrol Test Instance") kontrol.DefaultPort = 4099 kntrl := kontrol.New(conf.Copy(), "0.1.0") p := kontrol.NewPostgres(nil, kntrl.Kite.Log) kntrl.SetKeyPairStorage(p) kntrl.SetStorage(p) kntrl.AddKeyPair("", testkeys.Public, testkeys.Private) go kntrl.Run() <-kntrl.Kite.ServerReadyNotify() // Power up kloud kite log.Println("Starting Kloud Test Instance") kloudKite = kite.New("kloud", "0.0.1") kloudKite.Config = conf.Copy() kloudKite.Config.Port = 4002 kiteURL := &url.URL{Scheme: "http", Host: "localhost:4002", Path: "/kite"} _, err = kloudKite.Register(kiteURL) if err != nil { log.Fatal("kloud ", err.Error()) } awsProvider, slProvider = providers() // Add Kloud handlers kld := kloudWithProviders(awsProvider, slProvider) kloudKite.HandleFunc("plan", kld.Plan) kloudKite.HandleFunc("apply", kld.Apply) kloudKite.HandleFunc("bootstrap", kld.Bootstrap) kloudKite.HandleFunc("authenticate", kld.Authenticate) kloudKite.HandleFunc("build", kld.Build) kloudKite.HandleFunc("destroy", kld.Destroy) kloudKite.HandleFunc("stop", kld.Stop) kloudKite.HandleFunc("start", kld.Start) kloudKite.HandleFunc("reinit", kld.Reinit) kloudKite.HandleFunc("resize", kld.Resize) kloudKite.HandleFunc("restart", kld.Restart) kloudKite.HandleFunc("event", kld.Event) kloudKite.HandleFunc("createSnapshot", kld.CreateSnapshot) kloudKite.HandleFunc("deleteSnapshot", kld.DeleteSnapshot) go kloudKite.Run() <-kloudKite.ServerReadyNotify() // Power up our terraformer kite log.Println("Starting Terraform Test Instance") tConf := &terraformer.Config{ Port: 2300, Region: "dev", Environment: "dev", AWS: terraformer.AWS{ Key: os.Getenv("TERRAFORMER_KEY"), Secret: os.Getenv("TERRAFORMER_SECRET"), Bucket: "koding-terraformer-state-dev", }, LocalStorePath: filepath.Join(repoPath, filepath.FromSlash("go/data/terraformer")), } t, err := terraformer.New(tConf, logging.NewCustom("terraformer", false)) if err != nil { log.Fatal("terraformer ", err.Error()) } terraformerKite, err := terraformer.NewKite(t, tConf) if err != nil { log.Fatal("terraformer ", err.Error()) } // no need to register to kontrol, kloud talks directly via a secret key terraformerKite.Config = conf.Copy() terraformerKite.Config.Port = 2300 go terraformerKite.Run() <-terraformerKite.ServerReadyNotify() log.Println("=== Test instances are up and ready!. Executing now the tests... ===") // hashicorp.terraform outputs many logs, discard them log.SetOutput(ioutil.Discard) }