コード例 #1
0
ファイル: stack_test.go プロジェクト: koding/koding
func newDoBaseStack() (*provider.BaseStack, error) {
	log := logging.NewCustom("test", true)

	testTemplate := `{
    "variable": {
        "username": {
            "default": "testuser"
        }
    },
    "provider": {
        "digitalocean": {
            "token": "${var.digitalocean_access_token}"
        }
    },
    "resource": {
        "digitalocean_droplet": {
            "example": {
                "name": "web-1",
                "image": "ubuntu-14-04-x64",
                "region": "nyc2",
                "size": "512mb",
                "user_data": "sudo apt-get install sl -y\ntouch /tmp/${var.username}.txt"
            }
        }
    }
}`

	template, err := provider.ParseTemplate(testTemplate, log)
	if err != nil {
		return nil, err
	}

	return &provider.BaseStack{
		Provider: doProvider,
		Req: &kite.Request{
			Username: "******",
		},
		Arg: &stack.BootstrapRequest{
			Provider:  "digitalocean",
			GroupName: "testgroup",
		},
		Keys: &publickeys.Keys{
			PublicKey: "random-publickey",
		},
		Builder: &provider.Builder{
			Template: template,
		},
		Session: &session.Session{
			Userdata: &userdata.Userdata{
				KlientURL: "https://example-klient.com",
				Keycreator: &keycreator.Key{
					KontrolURL:        "https://example-kontrol.com",
					KontrolPrivateKey: testkeys.Private,
					KontrolPublicKey:  testkeys.Public,
				},
			},
		},
		KlientIDs: stack.KiteMap(map[string]string{}),
	}, nil
}
コード例 #2
0
ファイル: config.go プロジェクト: koding/koding
// NewClient returns client with required properties for accessing remote
// klient.
func NewClient() (*Client, error) {
	// Parse kite.key only once.
	if err := once.Do(newConfig); err != nil {
		return nil, err
	}

	k := kite.New(Name, Version)
	k.Config = config.Copy()

	if debug {
		k.SetLogLevel(kite.DEBUG)
	}

	c := &Client{
		Kite: k,
		Log:  logging.NewCustom(Name, debug),
	}

	c.Log.Debug("starting provider-vagrant in debug mode")

	c.Vagrant = &vagrantapi.Klient{
		Kite:  k,
		Log:   c.Log.New("vagrantapi"),
		Debug: debug,
	}

	return c, nil
}
コード例 #3
0
// check if it was added previously, if not create a new vagrantUtil
// instance
func (h *Handlers) vagrantutil(path string, debug bool) (*vagrantutil.Vagrant, error) {
	path = h.absolute(path)

	h.pathsMu.Lock()
	defer h.pathsMu.Unlock()

	v, ok := h.paths[path]
	if !ok {
		var err error
		v, err = vagrantutil.NewVagrant(path)
		if err != nil {
			return nil, err
		}

		if debug || h.opts.Debug {
			v.Log = logging.NewCustom("vagrantutil", true)
		}

		// Set explicitely to virtualbox to overwrite any default
		// provider that may be set system-wide.
		v.ProviderName = "virtualbox"

		h.paths[path] = v
	}

	return v, nil
}
コード例 #4
0
ファイル: main.go プロジェクト: koding/koding
func main() {
	if accessKey == "" {
		die("AWS_ACCESS_KEY is not set")
	}
	if secretKey == "" {
		die("AWS_SECRET_KEY is not set")
	}
	if hostedZone == "" {
		die("ROUTE53_HOSTED_ZONE is not set")
	}

	opts := &dnsclient.Options{
		Creds:       credentials.NewStaticCredentials(accessKey, secretKey, ""),
		HostedZone:  hostedZone,
		Log:         logging.NewCustom("dnsclient", os.Getenv("ROUTE53_DEBUG") == "1"),
		SyncTimeout: 5 * time.Minute,
	}

	if d, err := time.ParseDuration(os.Getenv("ROUTE53_TIMEOUT")); err == nil {
		opts.SyncTimeout = d
	}

	opts.Log.Debug("Options: %# v", opts)

	var err error
	client, err = dnsclient.NewRoute53Client(opts)
	if err != nil {
		die(err)
	}

	if err := Resources.Main(os.Args[1:]); err != nil {
		die(err)
	}
}
コード例 #5
0
ファイル: stacker.go プロジェクト: koding/koding
// BaseStack builds new base stack for the given context value.
func (s *Stacker) BaseStack(ctx context.Context) (*BaseStack, error) {
	bs := &BaseStack{
		Planner: &Planner{
			Provider:     s.Provider.Name,
			ResourceType: s.Provider.resourceName(),
			Log:          s.Log,
		},
		Provider:  s.Provider,
		KlientIDs: make(stack.KiteMap),
		Klients:   make(map[string]*DialState),
		TunnelURL: s.TunnelURL,
		Keys:      s.SSHKey,
	}

	var ok bool
	if bs.Req, ok = request.FromContext(ctx); !ok {
		return nil, errors.New("request not available in context")
	}

	req, ok := stack.TeamRequestFromContext(ctx)
	if !ok {
		return nil, errors.New("team request not available in context")
	}

	if bs.Session, ok = session.FromContext(ctx); !ok {
		return nil, errors.New("session not available in context")
	}

	bs.Log = s.Log.New(req.GroupName)

	if traceID, ok := stack.TraceFromContext(ctx); ok {
		bs.Log = logging.NewCustom("kloud-"+req.Provider, true).New(traceID)
		bs.TraceID = traceID
	}

	if keys, ok := publickeys.FromContext(ctx); ok {
		bs.Keys = keys
	}

	if ev, ok := eventer.FromContext(ctx); ok {
		bs.Eventer = ev
	}

	builderOpts := &BuilderOptions{
		Log:       s.Log.New("stackplan"),
		CredStore: s.CredStore,
	}

	bs.Builder = NewBuilder(builderOpts)

	if err := bs.Builder.BuildTeam(req.GroupName); err != nil {
		return nil, err
	}

	if !bs.Builder.Team.IsSubActive() {
		return nil, stack.NewError(stack.ErrTeamSubIsNotActive)
	}

	return bs, nil
}
コード例 #6
0
ファイル: stacker.go プロジェクト: koding/koding
func (s *Stacker) BuildBaseMachine(ctx context.Context, m *models.Machine) (*BaseMachine, error) {
	req, ok := request.FromContext(ctx)
	if !ok {
		return nil, errors.New("request context is not available")
	}

	bm := &BaseMachine{
		Machine: m,
		Session: &session.Session{
			DB:       s.DB,
			Kite:     s.Kite,
			Userdata: s.Userdata,
			Log:      s.Log.New(m.ObjectId.Hex()),
		},
		Credential: s.Provider.newCredential(),
		Bootstrap:  s.Provider.newBootstrap(),
		Metadata:   s.Provider.newMetadata(nil),
		Req:        req,
		Provider:   s.Provider.Name,
		Debug:      s.Debug,
	}

	// NOTE(rjeczalik): "internal" method is used by (*Queue).CheckAWS
	if req.Method != "internal" {
		// get user model which contains user ssh keys or the list of users that
		// are allowed to use this machine
		if len(m.Users) == 0 {
			return nil, errors.New("permitted users list is empty")
		}

		// get the user from the permitted list. If the list contains more than one
		// allowed person, fetch the one that is the same as requesterName, if
		// not pick up the first one.
		var err error
		bm.User, err = modelhelper.GetPermittedUser(req.Username, bm.Users)
		if err != nil {
			return nil, err
		}

		if err := s.ValidateUser(bm.User, bm.Users, req); err != nil {
			return nil, err
		}
	}

	if traceID, ok := stack.TraceFromContext(ctx); ok {
		bm.Log = logging.NewCustom("kloud-"+s.Provider.Name, true).New(m.ObjectId.Hex()).New(traceID)
		bm.Debug = true
		bm.TraceID = traceID
	}

	ev, ok := eventer.FromContext(ctx)
	if ok {
		bm.Eventer = ev
	}

	s.Log.Debug("BaseMachine: %+v", bm)

	return bm, nil
}
コード例 #7
0
ファイル: iter.go プロジェクト: koding/koding
// NewIterOptions Sets the default values for iterOptions
func NewIterOptions() *iterOptions {
	return &iterOptions{
		Skip:       0,
		Limit:      1000,
		Filter:     modelhelper.Selector{},
		RetryCount: 50,
		Log:        logging.NewCustom("Iter", false),
	}
}
コード例 #8
0
func main() {
	c, err := configure()
	if err != nil {
		log.Fatal("Reading config failed: ", err.Error())
	}

	conf := &asgd.Config{
		Name:            fmt.Sprintf("%s-%s", "tunnelproxymanager", c.EBEnvName),
		AccessKeyID:     c.AccessKeyID,
		SecretAccessKey: c.SecretAccessKey,
		Region:          c.Region,
		AutoScalingName: c.AutoScalingName,
		Debug:           c.Debug,
	}

	session, err := asgd.Configure(conf)
	if err != nil {
		log.Fatal("Reading config failed: ", err.Error())
	}

	log := logging.NewCustom(Name, conf.Debug)
	// remove formatting from call stack and output correct line
	log.SetCallDepth(1)

	route53Session := awssession.New(&aws.Config{
		Credentials: credentials.NewStaticCredentials(
			c.Route53AccessKeyID,
			c.Route53SecretAccessKey,
			"",
		),
		Region:     aws.String(conf.Region),
		MaxRetries: aws.Int(5),
	})

	// create record manager
	recordManager := tunnelproxymanager.NewRecordManager(route53Session, log, conf.Region, c.HostedZone)
	if err := recordManager.Init(); err != nil {
		log.Fatal(err.Error())
	}

	// create lifecycle
	l := asgd.NewLifeCycle(session, log, conf.AutoScalingName)

	// configure lifecycle with system name
	if err := l.Configure(conf.Name); err != nil {
		log.Fatal(err.Error())
	}

	done := registerSignalHandler(l, log)

	// listen to lifecycle events
	if err := l.Listen(recordManager.ProcessFunc); err != nil {
		log.Fatal(err.Error())
	}

	<-done
}
コード例 #9
0
ファイル: client.go プロジェクト: koding/koding
// NewClient gives new, unstarted tunnel client for the given options.
func NewClient(opts *ClientOptions) (*Client, error) {
	optsCopy := *opts

	if optsCopy.Log == nil {
		optsCopy.Log = logging.NewCustom("tunnelclient", optsCopy.Debug)
	}

	// TODO(rjeczalik): fix production to use WebSocket by default
	//
	// BUG(rjeczalik): starting a kite that is not registered to
	// kontrol will prevent the kite from updating it's keypair,
	// when it changes in kontrol - the only fix is to restart
	// kite process.
	k := kite.New("tunnelclient", "0.0.1")
	k.Config = optsCopy.Kite.Config.Copy()
	k.Config.Transport = config.WebSocket

	c := &Client{
		kite:          k,
		opts:          &optsCopy,
		tunnelKiteURL: optsCopy.tunnelKiteURL(),
		stateChanges:  make(chan *tunnel.ClientStateChange, 128),
		regserv:       make(chan map[string]*Tunnel, 1),
		services:      make(Services),
		routes:        make(map[int]string),
	}

	// If VirtualHost was configured, try to connect to it first.
	if c.opts.LastVirtualHost != "" {
		c.tunnelKiteURL = fmt.Sprintf("http://%s/kite", c.opts.LastVirtualHost)
		c.connected = &RegisterResult{
			VirtualHost: c.opts.LastVirtualHost,
			ServerAddr:  c.opts.LastVirtualHost,
		}
	}

	c.kite.ClientFunc = httputil.ClientFunc(opts.Debug)

	cfg := &tunnel.ClientConfig{
		FetchIdentifier: c.fetchIdent,
		FetchServerAddr: c.fetchServerAddr,
		FetchLocalAddr:  c.fetchLocalAddr,
		LocalAddr:       c.opts.LocalAddr,
		Debug:           c.opts.Debug,
		Log:             c.opts.Log.New("transport"),
		StateChanges:    c.stateChanges,
	}

	client, err := tunnel.NewClient(cfg)
	if err != nil {
		return nil, err
	}

	c.client = client

	return c, nil
}
コード例 #10
0
ファイル: keygentest.go プロジェクト: koding/koding
// Config creates new gateway.Config value from the given flags.
func (f *Flags) Config() *keygen.Config {
	return &keygen.Config{
		AccessKey:  f.AccessKey,
		SecretKey:  f.SecretKey,
		Bucket:     f.Bucket,
		AuthExpire: f.Expire,
		Region:     f.Region,
		Log:        logging.NewCustom("gateway-test", testing.Verbose()),
	}
}
コード例 #11
0
ファイル: vagrant.go プロジェクト: koding/koding
// Action is an entry point for "vagrant" subcommand.
func (v *Vagrant) Action(args []string) error {
	k, err := kloudClient()
	if err != nil {
		return err
	}
	vapi := &vagrantapi.Klient{
		Kite:  k.LocalKite,
		Log:   logging.NewCustom("vagrant", flagDebug),
		Debug: true,
	}

	ctx := context.Background()
	ctx = context.WithValue(ctx, vapiKey, vapi)
	v.Resource.ContextFunc = func([]string) context.Context { return ctx }
	return v.Resource.Main(args)
}
コード例 #12
0
func createLifeCycle(t *testing.T) *LifeCycle {
	config, awsconfig, err := Configure()
	if err != nil {
		t.Fatal(err.Error())
	}

	log := logging.NewCustom("asgd-test", config.Debug)
	log.SetCallDepth(1)

	l := NewLifeCycle(
		awsconfig,
		log,
		config.AutoScalingName,
	)
	return l
}
コード例 #13
0
ファイル: main.go プロジェクト: koding/koding
func main() {
	conf := &terraformer.Config{}

	mc := multiconfig.New()
	mc.Loader = multiconfig.MultiLoader(
		&multiconfig.TagLoader{},
		&multiconfig.EnvironmentLoader{},
		&multiconfig.EnvironmentLoader{Prefix: "KONFIG_TERRAFORMER"},
		&multiconfig.FlagLoader{},
	)

	mc.MustLoad(conf)

	if !conf.TerraformDebug {
		// hashicorp.terraform outputs many logs, discard them
		log.SetOutput(ioutil.Discard)
	}

	log := logging.NewCustom(terraformer.Name, conf.Debug)

	// init terraformer
	t, err := terraformer.New(conf, log)
	if err != nil {
		log.Fatal(err.Error())
	}

	k, err := terraformer.NewKite(t, conf)
	if err != nil {
		log.Fatal(err.Error())
	}

	if err := k.RegisterForever(k.RegisterURL(true)); err != nil {
		log.Fatal(err.Error())
	}

	go k.Run()
	<-k.ServerReadyNotify()
	log.Debug("Kite Started Listening")

	// terraformer can only be closed with signals, wait for any signal
	if err := t.Wait(); err != nil {
		log.Error("Err after waiting terraformer %s", err)
	}

	k.Close()
}
コード例 #14
0
func main() {
	c := &Conf{}
	mc := multiconfig.New()
	mc.Loader = multiconfig.MultiLoader(
		&multiconfig.TagLoader{},
		&multiconfig.EnvironmentLoader{},
		&multiconfig.EnvironmentLoader{Prefix: "ASGD"},
		&multiconfig.FlagLoader{},
	)
	mc.MustLoad(c)

	conf := &asgd.Config{
		Name:            c.Name,
		AccessKeyID:     c.AccessKeyID,
		SecretAccessKey: c.SecretAccessKey,
		Region:          c.Region,
		AutoScalingName: c.AutoScalingName,
		Debug:           c.Debug,
	}

	session, err := asgd.Configure(conf)
	if err != nil {
		log.Fatal("Reading config failed: ", err.Error())
	}

	log := logging.NewCustom("asgd", conf.Debug)
	// remove formatting from call stack and output correct line
	log.SetCallDepth(1)

	// create lifecycle
	l := asgd.NewLifeCycle(session, log, conf.AutoScalingName)

	// configure lifecycle with system name
	if err := l.Configure(conf.Name); err != nil {
		log.Fatal(err.Error())
	}

	done := registerSignalHandler(l, log)
	// listen to lifecycle events
	if err := l.Listen(process(c.Execute)); err != nil {
		log.Fatal(err.Error())
	}

	<-done
}
コード例 #15
0
ファイル: group.go プロジェクト: koding/koding
func (cmd *GroupFixDomain) Valid() error {
	if err := cmd.groupValues.Valid(); err != nil {
		return err
	}

	if len(cmd.values) == 0 {
		return errors.New("no usernames provided for -users flag")
	}

	if cmd.machine == "" {
		return errors.New("no value provided for -machine flag")
	}

	if cmd.env == "" {
		return errors.New("no value provided for -env flag")
	}

	zone := dnsZones[cmd.env]
	if zone == "" {
		return errors.New("invalid value provided for -env flag")
	}

	if cmd.access == "" {
		return errors.New("no value provided for -access flag")
	}

	if cmd.secret == "" {
		return errors.New("no value provided for -secret flag")
	}

	dnsOpts := &dnsclient.Options{
		Creds:      credentials.NewStaticCredentials(cmd.access, cmd.secret, ""),
		HostedZone: zone,
		Log:        logging.NewCustom("dns", flagDebug),
	}

	dns, err := dnsclient.NewRoute53Client(dnsOpts)
	if err != nil {
		return err
	}

	cmd.dns = dns

	return nil
}
コード例 #16
0
ファイル: e2e_test.go プロジェクト: koding/koding
func TestMain(m *testing.M) {
	rand.Seed(time.Now().UnixNano() + int64(os.Getpid()))
	argsTesting, argsConfig := splitArgs()
	flag.CommandLine.Parse(argsTesting)

	l := multiconfig.MultiLoader(
		&multiconfig.EnvironmentLoader{
			Prefix: "e2etest",
		},
		&multiconfig.FlagLoader{
			EnvPrefix: "e2etest",
			Args:      argsConfig,
		},
	)

	if err := l.Load(&Test); err != nil {
		die("unable to load configuration", err)
	}

	Test.Log = logging.NewCustom("test", Test.Debug)
	Test.setDefaults()

	if Test.Debug {
		fmt.Printf("e2etest.Test = %s\n", &Test)
	}

	ktrl := NewKontrol()
	ktrl.Start()

	exit := m.Run()

	if !Test.NoClean {
		Test.cleanupRoute53()
	}

	ktrl.Close()

	os.Exit(exit)
}
コード例 #17
0
ファイル: kloud.go プロジェクト: koding/koding
func newSession(conf *Config, k *kite.Kite) (*session.Session, error) {
	c := credentials.NewStaticCredentials(conf.AWSAccessKeyId, conf.AWSSecretAccessKey, "")

	kontrolPrivateKey, kontrolPublicKey := kontrolKeys(conf)

	klientFolder := "development/latest"
	if conf.ProdMode {
		k.Log.Info("Prod mode enabled")
		klientFolder = "production/latest"
	}

	k.Log.Info("Klient distribution channel is: %s", klientFolder)

	// Credential belongs to the `koding-kloud` user in AWS IAM's
	sess := &session.Session{
		DB:   modelhelper.Mongo,
		Kite: k,
		Userdata: &userdata.Userdata{
			Keycreator: &keycreator.Key{
				KontrolURL:        getKontrolURL(conf.KontrolURL),
				KontrolPrivateKey: kontrolPrivateKey,
				KontrolPublicKey:  kontrolPublicKey,
			},
			KlientURL: conf.KlientURL,
			TunnelURL: conf.TunnelURL,
			Bucket:    userdata.NewBucket("koding-klient", klientFolder, c),
		},
		Terraformer: &terraformer.Options{
			Endpoint:  "http://127.0.0.1:2300/kite",
			SecretKey: conf.TerraformerSecretKey,
			Kite:      k,
		},
		Log: logging.NewCustom("kloud", conf.DebugMode),
	}

	sess.DNSStorage = dnsstorage.NewMongodbStorage(sess.DB)

	return sess, nil
}
コード例 #18
0
ファイル: kite_test.go プロジェクト: koding/koding
func withKite(t *testing.T, f func(k *kite.Kite) error) {
	conf := &Config{}
	// Load the config, reads environment variables or from flags
	multiconfig.New().MustLoad(conf)

	// enable test mode
	conf.Test = true

	if !conf.Debug {
		// hashicorp.terraform outputs many logs, discard them
		log.SetOutput(ioutil.Discard)
	}

	log := logging.NewCustom(Name, conf.Debug)

	// init terraformer
	tr, err := New(conf, log)
	if err != nil {
		t.Errorf("err while creating terraformer %s", err.Error())
	}

	// init terraformer's kite
	k, err := NewKite(tr, conf)
	if err != nil {
		t.Errorf(err.Error())
	}
	k.Config.DisableAuthentication = true
	go k.Run()
	<-k.ServerReadyNotify()

	err = f(k)
	tr.Close()
	tr.Wait()
	k.Close()
	if err != nil {
		t.Errorf("failed with %s", err.Error())
	}
}
コード例 #19
0
ファイル: main_test.go プロジェクト: koding/koding
func kloudWithProviders(a *awsprovider.Provider, s *softlayer.Provider) *kloud.Kloud {
	kloudLogger := logging.NewCustom("kloud", true)
	sess := &session.Session{
		DB:         a.DB,
		Kite:       a.Kite,
		DNSClient:  a.DNSClient,
		DNSStorage: a.DNSStorage,
		AWSClients: a.EC2Clients,
		Userdata:   a.Userdata,
		Log:        kloudLogger,
	}

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

	userPrivateKey, userPublicKey := userMachinesKeys(
		os.Getenv("KLOUD_USER_PUBLICKEY"),
		os.Getenv("KLOUD_USER_PRIVATEKEY"),
	)

	kld.PublicKeys = &publickeys.Keys{
		KeyName:    publickeys.DeployKeyName,
		PrivateKey: userPrivateKey,
		PublicKey:  userPublicKey,
	}
	kld.Log = kloudLogger
	kld.DomainStorage = p.DNSStorage
	kld.Domainer = p.DNSClient
	kld.Locker = p
	kld.AddProvider("koding", p)
	kld.AddProvider("aws", a)
	kld.AddProvider("softlayer", s)
	return kld
}
コード例 #20
0
ファイル: keygen.go プロジェクト: koding/koding
	"time"

	"koding/kites/kloud/api/amazon"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/aws/aws-sdk-go/service/sts"
	"github.com/koding/kite"
	"github.com/koding/logging"
)

// TODO(rjeczalik): refactor Server/Provider to support multiple auth types (AuthRequest.Type)

var defaultLog = logging.NewCustom("keygen", false)

// DefaultBefore is a default behavior for Config.BeforeFunc field.
var DefaultBefore = func(expire time.Time) bool {
	return expire.Before(time.Now())
}

// Config defines configuration for Server, Provider and UserBucket types.
//
// TODO(rjeczalik): Split into ServerConfig / ClientConfig.
type Config struct {
	RootUser string // kite user allowed to impersonate other users; "koding" by default

	// S3 auth configuration
	AccessKey string // AWS access key; required
	SecretKey string // AWS secret key; required
コード例 #21
0
ファイル: store.go プロジェクト: koding/koding
package credential

import (
	"fmt"
	"net/http"
	"net/url"
	"sync"

	"koding/db/mongodb"
	"koding/kites/kloud/utils/object"

	"github.com/hashicorp/go-multierror"
	"github.com/koding/logging"
)

var defaultLog = logging.NewCustom("credential", false)

type validator interface {
	Valid() error
}

// NotFoundError represents an error fetching credentials.
//
// Identfiers of credentials that are missing in the underlying
// storage are listed in the Identifiers field.
type NotFoundError struct {
	Identifiers []string
	Err         error
}

// Error implements the built-in error interface.
コード例 #22
0
ファイル: dialer.go プロジェクト: koding/koding
package httputil

import (
	"fmt"
	"net"
	"net/http"
	"runtime/debug"
	"sync"
	"time"

	"github.com/koding/logging"
)

var defaultLog = logging.NewCustom("dialer", false)

type Dialer struct {
	*net.Dialer

	mu    sync.Mutex // protects conns
	once  sync.Once
	conns map[*Conn]struct{}
	tick  *time.Ticker
	opts  *ClientConfig
}

func NewDialer(cfg *ClientConfig) *Dialer {
	return &Dialer{
		Dialer: &net.Dialer{
			Timeout:   cfg.DialTimeout,
			KeepAlive: cfg.KeepAlive,
		},
コード例 #23
0
ファイル: tlsproxy.go プロジェクト: koding/koding
	"net"
	"net/http"
	"net/http/httptest"
	"os"
	"runtime"
	"strings"
	"sync/atomic"
	"time"

	"github.com/koding/logging"

	"koding/klient/tunnel/tlsproxy/pem"
	"koding/tools/util"
)

var defaultLog = logging.NewCustom("tlsproxy", false)

// Init adds local route for pem.Hostname to 127.0.0.1 address.
func Init() error {
	if runtime.GOOS == "windows" {
		return errors.New("not implemented")
	}

	f, err := os.OpenFile("/etc/hosts", os.O_RDWR|os.O_APPEND, 0644)
	if err != nil {
		return err
	}

	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		fields := strings.Fields(scanner.Text())
コード例 #24
0
	"time"

	konfig "koding/klient/config"
	"koding/klient/tunnel/tlsproxy/pem"
	"koding/logrotate"

	"github.com/boltdb/bolt"
	"github.com/cenkalti/backoff"
	multierror "github.com/hashicorp/go-multierror"
	"github.com/koding/kite"
	"github.com/koding/kite/dnode"
	"github.com/koding/logging"
	"github.com/koding/vagrantutil"
)

var defaultLog = logging.NewCustom("vagrant", false)

// Options are used to alternate default behavior of Handlers.
type Options struct {
	Home   string
	DB     *bolt.DB
	Log    kite.Logger
	Debug  bool
	Output func(string) (io.WriteCloser, error)
}

// Handlers define a set of kite handlers which is responsible of managing
// vagrant boxes on multiple different paths.
type Handlers struct {
	paths   map[string]*vagrantutil.Vagrant
	pathsMu sync.Mutex // protects paths
コード例 #25
0
ファイル: update_test.go プロジェクト: koding/koding
func TestUpdater(t *testing.T) {
	const timeout = 250 * time.Millisecond

	events := make(chan *mount.Event)
	defer close(events)

	s := StartUpdateServer()

	u := &app.Updater{
		Endpoint:    s.URL().String(),
		Interval:    50 * time.Millisecond,
		Log:         logging.NewCustom("updater", true),
		MountEvents: events,
	}

	go u.Run()

	if err := s.WaitForLatestReq(timeout); err != nil {
		t.Fatal(err)
	}

	// Send a mouting event and ensure no
	// update attempt was made afterwards.
	events <- &mount.Event{
		Path: "/path1",
		Type: mount.EventMounting,
	}

	// From this point update server will mark every latest request as illegal.
	s.Enable(false)

	if err := s.WaitForLatestReq(timeout); err == nil {
		t.Fatal("expected to timeout waiting for latest with disabled autoupdates")
	}

	// Send event that mouting succeeded, still no update requests expected.
	events <- &mount.Event{
		Path: "/path1",
		Type: mount.EventMounted,
	}

	if err := s.WaitForLatestReq(timeout); err == nil {
		t.Fatal("expected to timeout waiting for latest with disabled autoupdates")
	}

	// Send unmount event, but for different path that was previously reported
	// as mounted - this event should be ignored, autoupdates still disabled.
	events <- &mount.Event{
		Path: "/pathX",
		Type: mount.EventUnmounted,
	}

	// Only confirmed umount enables autoupdate, since unmounting
	// can traisition to failed - this event also does not enable autoupdates.
	events <- &mount.Event{
		Path: "/path1",
		Type: mount.EventUnmounting,
	}

	if err := s.WaitForLatestReq(timeout); err == nil {
		t.Fatal("expected to timeout waiting for latest with disabled autoupdates")
	}

	// Send unmount event for previous mount and expect autoupdates to turn on.
	events <- &mount.Event{
		Path: "/path1",
		Type: mount.EventUnmounted,
	}

	s.Enable(true)

	if err := s.WaitForLatestReq(timeout); err != nil {
		t.Fatal(err)
	}

	// Send mounting event, expect autoupdates to turn off, send the mount
	// was failed and expect the autoupdates to turn on again.
	events <- &mount.Event{
		Path: "/path1",
		Type: mount.EventMounting,
	}

	s.Enable(false)

	if err := s.WaitForLatestReq(timeout); err == nil {
		t.Fatal("expected to timeout waiting for latest with disabled autoupdates")
	}

	events <- &mount.Event{
		Path: "/path1",
		Type: mount.EventMounting,
		Err:  errors.New("mount failed"),
	}

	s.Enable(true)

	if err := s.WaitForLatestReq(timeout); err != nil {
		t.Fatal(err)
	}

	// Ensure no update request was made while the autoupdates
	// were expected to be disabled.
	if err := s.Err(); err != nil {
		t.Fatal(err)
	}
}
コード例 #26
0
		}
		defer testExec(output)()

		ok, err := vagrant.VboxIsVagrant()
		if err != nil {
			t.Errorf("%d: IsVagrant()=%s", i, err)
			continue
		}

		if ok != cas.ok {
			t.Errorf("%d: got %t, want %t", i, ok, cas.ok)
		}
	}
}

var h = vagrant.NewHandlers(&vagrant.Options{Log: logging.NewCustom("vagrant", true)})

func TestVboxLookupName(t *testing.T) {
	output := map[string]string{
		"VBoxManage list vms": vboxManageList,
	}
	defer testExec(output)()

	want := "urfve6cb85a2_default_1458910687825_39001"

	got, err := h.VboxLookupName("urfve6cb85a2")
	if err != nil {
		t.Fatalf("VboxLookupName()=%s", err)
	}

	if got != want {
コード例 #27
0
	"encoding/hex"
	"fmt"
	"io"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"

	"koding/klient/storage"

	"github.com/koding/logging"
)

var defaultLog = logging.NewCustom("logrotate", false)

// DefaultChecksumSize is a size of a part that is going to be checksummed.
//
// E.g. if your log file contains a lot of lines that have exact the same
// content and additionally those lines are long ones (>DefaultChecksumSize characters),
// you may want to increase the DefaultChecksumSize to ensure
// there are not false-positive checksum matches.
//
// TODO(rjeczalik): make Logger use configurable ChecksumSize
const DefaultChecksumSize = 256

// Metadata represents a metadata of a single object, e.g. file.
type Metadata struct {
	Key   string          `json:"key"`
	Parts []*MetadataPart `json:"parts"`
コード例 #28
0
ファイル: stack_test.go プロジェクト: koding/koding
func TestAzure_ApplyTemplate(t *testing.T) {
	log := logging.NewCustom("test", true)

	cred := &stack.Credential{
		Credential: &azure.Cred{
			PublishSettings:  "publish_settings",
			SSHKeyThumbprint: "12:23:45:56:67:89:90",
		},
		Bootstrap: &azure.Bootstrap{
			AddressSpace:     "10.10.10.10/16",
			StorageServiceID: "storage-serice",
			HostedServiceID:  "hosted-service",
			SecurityGroupID:  "security-group",
			VirtualNetworkID: "virtual-network",
			SubnetName:       "subnet",
		},
	}

	cases := map[string]struct {
		stackFile string
		wantFile  string
	}{
		"basic stack": {
			"testdata/basic-stack.json",
			"testdata/basic-stack.json.golden",
		},
		"basic stack with count=3": {
			"testdata/basic-stack-count-3.json",
			"testdata/basic-stack-count-3.json.golden",
		},
		"custom endpoint": {
			"testdata/custom-endpoint.json",
			"testdata/custom-endpoint.json.golden",
		},
	}

	for name, cas := range cases {
		t.Run(name, func(t *testing.T) {
			content, err := ioutil.ReadFile(cas.stackFile)
			if err != nil {
				t.Fatalf("ReadFile(%s)=%s", cas.stackFile, err)
			}

			want, err := ioutil.ReadFile(cas.wantFile)
			if err != nil {
				t.Fatalf("ReadFile(%s)=%s", cas.wantFile, err)
			}

			template, err := provider.ParseTemplate(string(content), log)
			if err != nil {
				t.Fatalf("ParseTemplate()=%s", err)
			}

			s := &azure.Stack{
				BaseStack: &provider.BaseStack{
					Session: &session.Session{
						Userdata: &userdata.Userdata{
							KlientURL: "http://127.0.0.1/klient.gz",
							Keycreator: &keycreator.Key{
								KontrolURL:        "http://127.0.0.1/kontrol/kite",
								KontrolPublicKey:  testkeys.Public,
								KontrolPrivateKey: testkeys.Private,
							},
						},
					},
					Builder: &provider.Builder{
						Template: template,
					},
					Req: &kite.Request{
						Username: "******",
					},
					KlientIDs: make(stack.KiteMap),
				},
			}

			stack, err := s.ApplyTemplate(cred)
			if err != nil {
				t.Fatalf("ApplyTemplate()=%s", err)
			}

			if err := equal(stack.Content, string(want)); err != nil {
				t.Fatal(err)
			}
		})
	}
}
コード例 #29
0
	kitecfg "github.com/koding/kite/config"
	"github.com/koding/logging"
)

// Transport is an interface that abstracts underlying
// RPC round trip.
//
// Default implementation used in this package is
// a kiteTransport, but plain net/rpc can also be
// used.
type Transport interface {
	Call(method string, arg, reply interface{}) error
}

// DefaultLog is a logger used by Client with nil Log.
var DefaultLog logging.Logger = logging.NewCustom("endpoint-kloud", false)

// DefaultClient is a default client used by Cache, Kite,
// KiteConfig and Kloud functions.
var DefaultClient = &Client{
	Transport: &KiteTransport{},
}

// Client is responsible for communication with Kloud kite.
type Client struct {
	// Transport is used for RPC communication.
	//
	// Required.
	Transport Transport

	cache *cfg.Cache
コード例 #30
0
ファイル: machine.go プロジェクト: koding/koding
	"errors"
	"strings"

	"koding/klient/config"

	"github.com/koding/logging"
)

var (
	// ErrMachineNotFound indicates that provided machine cannot be found.
	ErrMachineNotFound = errors.New("machine not found")
)

// DefaultLogger is a logger which can be used in machine related objects as
// a fallback logger when Log option is not provided.
var DefaultLogger = logging.NewCustom("machine", config.Konfig.Debug)

// ID is a unique identifier of the machine.
type ID string

// IDSlice represents a set of machine IDs.
type IDSlice []ID

// String implements fmt.Stringer interface. It pretty prints machine IDs.
func (ids IDSlice) String() string {
	strs := make([]string, len(ids))
	for i := range ids {
		strs[i] = string(ids[i])
	}

	return strings.Join(strs, ", ")