Example #1
0
func main() {
	flag.Parse()

	// Create a kite
	k := kite.New("math", "1.0.0")

	// Add our handler method
	k.HandleFunc("square", Square)

	// Get config from kite.Key directly, usually it's under ~/.kite/kite.key
	c := config.MustGet()
	k.Config = c
	k.Config.Port = *flagPort
	k.SetLogLevel(kite.DEBUG)
	k.Id = c.Id

	// by default it's already WebSocket
	if *flagTransport != "" && *flagTransport == "xhrpolling" {
		k.Config.Transport = config.XHRPolling
	}

	// Register to kite with this url
	kiteURL := &url.URL{Scheme: "http", Host: "localhost:" + strconv.Itoa(*flagPort), Path: "/kite"}

	// Register us ...
	err := k.RegisterForever(kiteURL)
	if err != nil {
		log.Fatal(err)
	}

	// And finally attach to a server and run it
	k.Run()
}
Example #2
0
func main() {
	// Create a kite
	k := kite.New("exp2", "1.0.0")
	k.Config = config.MustGet()

	onEvent := func(e *kite.Event, err *kite.Error) {
		fmt.Printf("e %+v\n", e)
		fmt.Printf("err %+v\n", err)
	}

	_, err := k.WatchKites(protocol.KontrolQuery{
		Username:    k.Config.Username,
		Environment: k.Config.Environment,
		Name:        "math",
		// ID: "48bb002b-79f6-4a4e-6bba-a40567a08b6c",
	}, onEvent)
	if err != nil {
		log.Fatalln(err)
	}

	// This is a bad example, it's just for testing the watch functionality :)
	fmt.Println("listening to events")

	select {}
}
Example #3
0
func NewKiteWrapper(cfg *conf.KiteConfig) *Wrapper {
	k := kite.New(cfg.Name, cfg.Version)
	k.Config = config.MustGet()
	k.Config.Port = cfg.Port

	return &Wrapper{k, cfg}
}
Example #4
0
func main() {
	flag.Parse()

	if *flagVersion {
		fmt.Println(reverseproxy.Version)
		os.Exit(0)
	}

	if *flagRegion == "" || *flagEnvironment == "" {
		log.Fatal("Please specify envrionment via -env and region via -region. Aborting.")
	}

	scheme := "http"
	if *flagCertFile != "" && *flagKeyFile != "" {
		scheme = "https"
	}

	conf := config.MustGet()
	conf.IP = *flagIp
	conf.Port = *flagPort
	conf.Region = *flagRegion
	conf.Environment = *flagEnvironment

	r := reverseproxy.New(conf)
	r.PublicHost = *flagPublicHost
	r.Scheme = scheme

	// Use server port if the public port is not defined
	if *flagPublicPort == 0 {
		*flagPublicPort = *flagPort
	}
	r.PublicPort = *flagPublicPort

	registerURL := &url.URL{
		Scheme: scheme,
		Host:   *flagPublicHost + ":" + strconv.Itoa(*flagPublicPort),
		Path:   "/kite",
	}

	r.Kite.Log.Info("Registering with register url %s", registerURL)
	if err := r.Kite.RegisterForever(registerURL); err != nil {
		r.Kite.Log.Fatal("Registering to Kontrol: %s", err)
	}

	if *flagCertFile == "" || *flagKeyFile == "" {
		log.Println("No cert/key files are defined. Running proxy unsecure.")
		err := r.ListenAndServe()
		if err != nil {
			log.Fatal("ListenAndServe: ", err)
		}
	} else {
		err := r.ListenAndServeTLS(*flagCertFile, *flagKeyFile)
		if err != nil {
			log.Fatal("ListenAndServe: ", err)
		}
	}
}
Example #5
0
func getKontrolURL(ownURL string) string {
	// read kontrolURL from kite.key if it doesn't exist.
	kontrolURL := kiteconfig.MustGet().KontrolURL

	if ownURL != "" {
		u, err := url.Parse(ownURL)
		if err != nil {
			log.Fatalln(err)
		}

		kontrolURL = u.String()
	}

	return kontrolURL
}
Example #6
0
func foo(c *gin.Context) {
	k := kite.New("api", "1.0.0")

	k.Config = config.MustGet()
	k.Config.Environment = "development"

	k.SetLogLevel(kite.DEBUG)
	fmt.Println(k.Config)

	// search a kite that has the same username and environment as us, but the
	kites, gkerr := k.GetKites(&protocol.KontrolQuery{
		Username:    k.Config.Username,
		Environment: k.Config.Environment,
		Name:        "foobar",
	})
	if gkerr != nil {
		fmt.Println("no kites found named foobar")
		k.Log.Fatal(gkerr.Error())
	}

	// there might be several kites that matches our query
	client := kites[0]

	fmt.Println("found a kite")
	fmt.Println(client.URL)

	connected, err := client.DialForever()
	if err != nil {
		k.Log.Fatal(err.Error())
	}

	// Wait until connected
	<-connected

	// Call a method of client kite
	response, err := client.TellWithTimeout("foo", 4*time.Second)
	if err != nil {
		k.Log.Error(err.Error())
	}

	// Print the result
	res, _ := response.String()

	c.String(200, "foo-"+res)
}
Example #7
0
func main() {
	// Create a kite
	k := kite.New("exp2", "1.0.0")
	k.Config = config.MustGet()

	kites, err := k.GetKites(&protocol.KontrolQuery{
		Username:    k.Config.Username,
		Environment: k.Config.Environment,
		Name:        "math",
	})
	if err != nil {
		log.Fatalln(err)
	}

	// Connect to remote kite
	defer kite.Close(kites[1:])

	mathWorker := kites[0]
	connected, err := mathWorker.DialForever()
	if err != nil {
		k.Log.Fatal(err.Error())
	}

	// Wait until connected
	<-connected

	// Call square method every second
	for _ = range time.Tick(time.Second) {
		i := rand.Intn(10)

		// Call a method of mathworker kite
		response, err := mathWorker.TellWithTimeout("square", 4*time.Second, i)
		if err != nil {
			k.Log.Error(err.Error())
			continue
		}

		// Print the result
		result := response.MustFloat64()
		fmt.Printf("input: %d  result: %.0f\n", i, result)
	}
}
Example #8
0
func main() {
	k := kite.New("pingpong", "1.0.0")
	k.Config = config.MustGet()
	k.Config.Environment = "development"
	k.Config.Port = 3002
	k.SetLogLevel(kite.DEBUG)

	k.HandleFunc("ping", func(r *kite.Request) (interface{}, error) {
		return "pong", nil
	})

	// Register to be a kite with this url
	kiteURL := &url.URL{Scheme: "http", Host: "127.0.0.1:" + strconv.Itoa(k.Config.Port), Path: "/kite"}
	err := k.RegisterForever(kiteURL)
	if err != nil {
		log.Fatal(err)
	}

	// And finally attach to a server and run it
	k.Run()
}
Example #9
0
func (c *Query) Run(args []string) int {
	c.KiteClient.Config = config.MustGet()
	c.KiteClient.Config.Transport = config.XHRPolling

	var query protocol.KontrolQuery

	flags := flag.NewFlagSet("query", flag.ExitOnError)
	flags.StringVar(&query.Username, "username", c.KiteClient.Kite().Username, "")
	flags.StringVar(&query.Environment, "environment", "", "")
	flags.StringVar(&query.Name, "name", "", "")
	flags.StringVar(&query.Version, "version", "", "")
	flags.StringVar(&query.Region, "region", "", "")
	flags.StringVar(&query.Hostname, "hostname", "", "")
	flags.StringVar(&query.ID, "id", "", "")
	flags.Parse(args)

	result, err := c.KiteClient.GetKites(&query)
	if err != nil {
		c.Ui.Error(err.Error())
		return 1
	}

	for i, client := range result {
		var k *protocol.Kite = &client.Kite
		c.Ui.Output(fmt.Sprintf(
			"%d\t%s/%s/%s/%s/%s/%s/%s\t%s",
			i+1,
			k.Username,
			k.Environment,
			k.Name,
			k.Version,
			k.Region,
			k.Hostname,
			k.ID,
			client.URL,
		))
	}

	return 0
}
Example #10
0
func main() {
	var (
		publicKeyFile  = flag.String("public-key", "", "")
		privateKeyFile = flag.String("private-key", "", "")
		ip             = flag.String("ip", "0.0.0.0", "")
		port           = flag.Int("port", 3999, "")
		publicHost     = flag.String("public-host", "127.0.0.1:3999", "")
		version        = flag.String("version", "0.0.1", "")
	)

	flag.Parse()

	if *publicKeyFile == "" {
		log.Fatalln("no -public-key given")
	}

	if *privateKeyFile == "" {
		log.Fatalln("no -private-key given")
	}

	publicKey, err := ioutil.ReadFile(*publicKeyFile)
	if err != nil {
		log.Fatalln("cannot read public key file")
	}

	privateKey, err := ioutil.ReadFile(*privateKeyFile)
	if err != nil {
		log.Fatalln("cannot read private key file")
	}

	conf := config.MustGet()
	conf.IP = *ip
	conf.Port = *port

	t := tunnelproxy.New(conf, *version, string(publicKey), string(privateKey))
	t.PublicHost = *publicHost

	t.Run()
}
Example #11
0
// New gives new, registered kloud kite.
//
// If conf contains invalid or missing configuration, it return non-nil error.
func New(conf *Config) (*Kloud, error) {
	k := kite.New(stack.NAME, stack.VERSION)
	k.Config = kiteconfig.MustGet()
	k.Config.Port = conf.Port

	k.ClientFunc = httputil.ClientFunc(conf.DebugMode)

	if conf.DebugMode {
		k.SetLogLevel(kite.DEBUG)
	}

	if conf.Region != "" {
		k.Config.Region = conf.Region
	}

	if conf.Environment != "" {
		k.Config.Environment = conf.Environment
	}

	// TODO(rjeczalik): refactor modelhelper methods to not use global DB
	modelhelper.Initialize(conf.MongoURL)

	sess, err := newSession(conf, k)
	if err != nil {
		return nil, err
	}

	e := newEndpoints(conf)

	sess.Log.Debug("Konfig.Endpoints: %s", util.LazyJSON(e))

	authUsers := map[string]string{
		"kloudctl": conf.KloudSecretKey,
	}

	restClient := httputil.DefaultRestClient(conf.DebugMode)

	storeOpts := &credential.Options{
		MongoDB: sess.DB,
		Log:     sess.Log.New("stackcred"),
		Client:  restClient,
	}

	if !conf.NoSneaker {
		storeOpts.CredURL = e.Social().WithPath("/credential").Private.URL
	}

	sess.Log.Debug("storeOpts: %+v", storeOpts)

	userPrivateKey, userPublicKey := userMachinesKeys(conf.UserPublicKey, conf.UserPrivateKey)

	stacker := &provider.Stacker{
		DB:             sess.DB,
		Log:            sess.Log,
		Kite:           sess.Kite,
		Userdata:       sess.Userdata,
		Debug:          conf.DebugMode,
		KloudSecretKey: conf.KloudSecretKey,
		CredStore:      credential.NewStore(storeOpts),
		TunnelURL:      conf.TunnelURL,
		SSHKey: &publickeys.Keys{
			KeyName:    publickeys.DeployKeyName,
			PrivateKey: userPrivateKey,
			PublicKey:  userPublicKey,
		},
	}

	stats := common.MustInitMetrics(Name)

	kloud := &Kloud{
		Kite:  k,
		Stack: stack.New(),
		Queue: &queue.Queue{
			Interval: 5 * time.Second,
			Log:      sess.Log.New("queue"),
			Kite:     k,
			MongoDB:  sess.DB,
		},
	}

	authFn := func(opts *api.AuthOptions) (*api.Session, error) {
		s, err := modelhelper.FetchOrCreateSession(opts.User.Username, opts.User.Team)
		if err != nil {
			return nil, err
		}

		return &api.Session{
			ClientID: s.ClientId,
			User: &api.User{
				Username: s.Username,
				Team:     s.GroupName,
			},
		}, nil
	}

	transport := &api.Transport{
		RoundTripper: storeOpts.Client.Transport,
		AuthFunc:     api.NewCache(authFn).Auth,
		Debug:        conf.DebugMode,
	}

	if conf.DebugMode {
		transport.Log = sess.Log
	}

	kloud.Stack.Endpoints = e
	kloud.Stack.Userdata = sess.Userdata
	kloud.Stack.DescribeFunc = provider.Desc
	kloud.Stack.CredClient = credential.NewClient(storeOpts)
	kloud.Stack.MachineClient = machine.NewClient(machine.NewMongoDatabase())
	kloud.Stack.TeamClient = team.NewClient(team.NewMongoDatabase())
	kloud.Stack.PresenceClient = client.NewInternal(e.Social().Private.String())
	kloud.Stack.PresenceClient.HTTPClient = restClient
	kloud.Stack.RemoteClient = &remoteapi.Client{
		Client:    storeOpts.Client,
		Transport: transport,
		Endpoint:  e.Koding.Private.URL,
	}

	kloud.Stack.ContextCreator = func(ctx context.Context) context.Context {
		return session.NewContext(ctx, sess)
	}

	kloud.Stack.Metrics = stats

	// RSA key pair that we add to the newly created machine for
	// provisioning.
	kloud.Stack.PublicKeys = stacker.SSHKey
	kloud.Stack.DomainStorage = sess.DNSStorage
	kloud.Stack.Domainer = sess.DNSClient
	kloud.Stack.Locker = stacker
	kloud.Stack.Log = sess.Log
	kloud.Stack.SecretKey = conf.KloudSecretKey

	for _, p := range provider.All() {
		s := stacker.New(p)

		if err = kloud.Stack.AddProvider(p.Name, s); err != nil {
			return nil, err
		}

		kloud.Queue.Register(s)

		sess.Log.Debug("registering %q provider", p.Name)
	}

	go kloud.Queue.Run()

	if conf.KeygenAccessKey != "" && conf.KeygenSecretKey != "" {
		cfg := &keygen.Config{
			AccessKey:  conf.KeygenAccessKey,
			SecretKey:  conf.KeygenSecretKey,
			Region:     conf.KeygenRegion,
			Bucket:     conf.KeygenBucket,
			AuthExpire: conf.KeygenTokenTTL,
			AuthFunc:   kloud.Stack.ValidateUser,
			Kite:       k,
		}

		kloud.Keygen = keygen.NewServer(cfg)
	} else {
		k.Log.Warning(`disabling "keygen" methods due to missing S3/STS credentials`)
	}

	// Teams/stack handling methods.
	k.HandleFunc("plan", kloud.Stack.Plan)
	k.HandleFunc("apply", kloud.Stack.Apply)
	k.HandleFunc("describeStack", kloud.Stack.Status)
	k.HandleFunc("authenticate", kloud.Stack.Authenticate)
	k.HandleFunc("bootstrap", kloud.Stack.Bootstrap)
	k.HandleFunc("import", kloud.Stack.Import)

	// Credential handling.
	k.HandleFunc("credential.describe", kloud.Stack.CredentialDescribe)
	k.HandleFunc("credential.list", kloud.Stack.CredentialList)
	k.HandleFunc("credential.add", kloud.Stack.CredentialAdd)

	// Authorization handling.
	k.HandleFunc("auth.login", kloud.Stack.AuthLogin)
	k.HandleFunc("auth.passwordLogin", kloud.Stack.AuthPasswordLogin).DisableAuthentication()

	// Configuration handling.
	k.HandleFunc("config.metadata", kloud.Stack.ConfigMetadata)

	// Team handling.
	k.HandleFunc("team.list", kloud.Stack.TeamList)
	k.HandleFunc("team.whoami", kloud.Stack.TeamWhoami)

	// Machine handling.
	k.HandleFunc("machine.list", kloud.Stack.MachineList)

	// Single machine handling.
	k.HandleFunc("stop", kloud.Stack.Stop)
	k.HandleFunc("start", kloud.Stack.Start)
	k.HandleFunc("info", kloud.Stack.Info)
	k.HandleFunc("event", kloud.Stack.Event)

	// Klient proxy methods.
	k.HandleFunc("admin.add", kloud.Stack.AdminAdd)
	k.HandleFunc("admin.remove", kloud.Stack.AdminRemove)

	k.HandleHTTPFunc("/healthCheck", artifact.HealthCheckHandler(Name))
	k.HandleHTTPFunc("/version", artifact.VersionHandler())

	for worker, key := range authUsers {
		worker, key := worker, key
		k.Authenticators[worker] = func(r *kite.Request) error {
			if r.Auth.Key != key {
				return errors.New("wrong secret key passed, you are not authenticated")
			}
			return nil
		}
	}

	if conf.DebugMode {
		// This should be actually debug level 2. It outputs every single Kite
		// message and enables the kite debugging system. So enable it only if
		// you need it.
		// k.SetLogLevel(kite.DEBUG)
		k.Log.Info("Debug mode enabled")
	}

	if conf.TestMode {
		k.Log.Info("Test mode enabled")
	}

	registerURL := k.RegisterURL(!conf.Public)
	if conf.RegisterURL != "" {
		u, err := url.Parse(conf.RegisterURL)
		if err != nil {
			return nil, fmt.Errorf("Couldn't parse register url: %s", err)
		}

		registerURL = u
	}

	if err := k.RegisterForever(registerURL); err != nil {
		return nil, err
	}

	return kloud, nil
}
Example #12
0
File: main.go Project: gotao/kite
func main() {
	conf := new(Kontrol)

	multiconfig.New().MustLoad(conf)

	publicKey, err := ioutil.ReadFile(conf.PublicKeyFile)
	if err != nil {
		log.Fatalf("cannot read public key file: %s", err.Error())
	}

	privateKey, err := ioutil.ReadFile(conf.PrivateKeyFile)
	if err != nil {
		log.Fatalf("cannot read private key file: %s", err.Error())
	}

	if conf.Initial {
		initialKey(conf, publicKey, privateKey)
		os.Exit(0)
	}

	kiteConf := config.MustGet()
	kiteConf.IP = conf.Ip
	kiteConf.Port = conf.Port

	k := kontrol.New(kiteConf, conf.Version)

	if conf.TLSCertFile != "" || conf.TLSKeyFile != "" {
		cert, err := tls.LoadX509KeyPair(conf.TLSCertFile, conf.TLSKeyFile)
		if err != nil {
			log.Fatalf("cannot load TLS certificate: %s", err.Error())
		}

		k.Kite.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
	}

	if conf.RegisterUrl != "" {
		k.RegisterURL = conf.RegisterUrl
	}

	switch os.Getenv("KONTROL_STORAGE") {
	case "etcd":
		k.SetStorage(kontrol.NewEtcd(conf.Machines, k.Kite.Log))
	case "postgres":
		postgresConf := &kontrol.PostgresConfig{
			Host:     conf.Postgres.Host,
			Port:     conf.Postgres.Port,
			Username: conf.Postgres.Username,
			Password: conf.Postgres.Password,
			DBName:   conf.Postgres.DBName,
		}

		p := kontrol.NewPostgres(postgresConf, k.Kite.Log)
		k.SetStorage(p)
		k.SetKeyPairStorage(p)
	default:
		k.SetStorage(kontrol.NewEtcd(conf.Machines, k.Kite.Log))
	}

	k.AddKeyPair("", string(publicKey), string(privateKey))
	k.Kite.SetLogLevel(kite.DEBUG)
	k.Run()
}
Example #13
0
func New(c *Config) *kontrol.Kontrol {
	modelhelper.Initialize(c.MongoURL)

	publicKey, err := ioutil.ReadFile(FindPath(c.PublicKey))
	if err != nil {
		log.Fatalln(err.Error())
	}

	privateKey, err := ioutil.ReadFile(FindPath(c.PrivateKey))
	if err != nil {
		log.Fatalln(err.Error())
	}

	kiteConf := config.MustGet()

	if c.Environment != "" {
		kiteConf.Environment = c.Environment
	}

	if c.Region != "" {
		kiteConf.Region = c.Region
	}

	if c.Port != 0 {
		kiteConf.Port = c.Port
	}

	// TODO: Move the metrics instance somewhere meaningful
	met := common.MustInitMetrics(Name)

	kon := kontrol.NewWithoutHandlers(kiteConf, Version)
	kon.TokenNoNBF = true

	kon.Kite.HandleFunc("register",
		metricKiteHandler(met, "HandleRegister", kon.HandleRegister),
	)

	kon.Kite.HandleFunc("registerMachine",
		metricKiteHandler(met, "HandleMachine", kon.HandleMachine),
	).DisableAuthentication()

	kon.Kite.HandleFunc("getKodingKites",
		metricKiteHandler(
			met, "HandleGetKodingKites", HandleGetKodingKites(kon.HandleGetKites, kiteConf.Environment),
		),
	)

	kon.Kite.HandleFunc("getKites",
		metricKiteHandler(met, "HandleGetKites", kon.HandleGetKites),
	)
	kon.Kite.HandleFunc("getToken",
		metricKiteHandler(met, "HandleGetToken", kon.HandleGetToken),
	)
	kon.Kite.HandleFunc("getKey",
		metricKiteHandler(met, "HandleGetKey", kon.HandleGetKey),
	)

	kon.Kite.HandleHTTPFunc("/heartbeat",
		metricHandler(met, "HandleHeartbeat", kon.HandleHeartbeat),
	)

	kon.Kite.HandleHTTP("/register", throttledHandler(
		metricHandler(met, "HandleRegisterHTTP", kon.HandleRegisterHTTP),
	))

	kon.AddAuthenticator("sessionID", authenticateFromSessionID)
	kon.MachineAuthenticate = authenticateMachine

	switch c.Storage {
	case "etcd":
		kon.SetStorage(kontrol.NewEtcd(c.Machines, kon.Kite.Log))
	case "postgres":
		postgresConf := &kontrol.PostgresConfig{
			Host:     c.Postgres.Host,
			Port:     c.Postgres.Port,
			Username: c.Postgres.Username,
			Password: c.Postgres.Password,
			DBName:   c.Postgres.DBName,
		}
		p := kontrol.NewPostgres(postgresConf, kon.Kite.Log)
		p.DB.SetMaxOpenConns(20)
		kon.SetStorage(p)

		s := kontrol.NewCachedStorage(
			p,
			kontrol.NewMemKeyPairStorageTTL(time.Minute*5),
		)
		kon.SetKeyPairStorage(s)
		// kon.MachineKeyPicker = newMachineKeyPicker(p)
	default:
		panic(fmt.Sprintf("storage is not found: %q", c.Storage))
	}

	kon.AddKeyPair("", string(publicKey), string(privateKey))

	if c.TLSKeyFile != "" && c.TLSCertFile != "" {
		kon.Kite.UseTLSFile(c.TLSCertFile, c.TLSKeyFile)
	}

	return kon
}