Beispiel #1
0
func ServeHTTP() error {
	logger := log.New()
	installer := NewInstaller(logger)

	api := &httpAPI{
		Installer: installer,
		logger:    logger,
		clientConfig: installerJSConfig{
			Endpoints: map[string]string{
				"clusters":           "/clusters",
				"cluster":            "/clusters/:id",
				"upload_backup":      "/clusters/:id/upload-backup",
				"cert":               "/clusters/:id/ca-cert",
				"events":             "/events",
				"prompt":             "/clusters/:id/prompts/:prompt_id",
				"credentials":        "/credentials",
				"regions":            "/regions",
				"azureSubscriptions": "/azure/subscriptions",
			},
		},
	}

	if creds, err := aws.EnvCreds(); err == nil {
		api.AWSEnvCreds = creds
		if c, err := creds.Credentials(); err == nil {
			api.clientConfig.HasAWSEnvCredentials = true
			api.clientConfig.AWSEnvCredentialsID = c.AccessKeyID
		}
	}

	httpRouter := httprouter.New()

	httpRouter.GET("/", api.ServeTemplate)
	httpRouter.GET("/credentials", api.ServeTemplate)
	httpRouter.GET("/credentials/:id", api.ServeTemplate)
	httpRouter.GET("/clusters/:id", api.ServeTemplate)
	httpRouter.POST("/clusters/:id/upload-backup", api.ReceiveBackup)
	httpRouter.GET("/clusters/:id/ca-cert", api.GetCert)
	httpRouter.GET("/clusters/:id/delete", api.ServeTemplate)
	httpRouter.GET("/oauth/azure", api.ServeTemplate)
	httpRouter.DELETE("/clusters/:id", api.DeleteCluster)
	httpRouter.GET("/clusters", api.RedirectRoot)
	httpRouter.POST("/clusters", api.LaunchCluster)
	httpRouter.GET("/events", api.Events)
	httpRouter.POST("/clusters/:id/prompts/:prompt_id", api.Prompt)
	httpRouter.GET("/assets/*assetPath", api.ServeAsset)
	httpRouter.POST("/credentials", api.NewCredential)
	httpRouter.DELETE("/credentials/:type/:id", api.DeleteCredential)
	httpRouter.GET("/regions", api.GetCloudRegions)
	httpRouter.GET("/azure/subscriptions", api.GetAzureSubscriptions)

	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return err
	}
	addr := fmt.Sprintf("http://localhost:%d", l.Addr().(*net.TCPAddr).Port)
	fmt.Printf("Open %s in your browser to continue.\n", addr)
	browser.OpenURL(addr)
	return http.Serve(l, api.CorsHandler(httpRouter, addr))
}
Beispiel #2
0
func ServeHTTP() error {
	api := &httpAPI{
		InstallerPrompts: make(map[string]*httpPrompt),
		InstallerStacks:  make(map[string]*httpInstaller),
	}

	if creds, err := aws.EnvCreds(); err == nil {
		api.AWSEnvCreds = creds
	}

	httpRouter := httprouter.New()

	httpRouter.GET("/", api.ServeTemplate)
	httpRouter.GET("/install", api.ServeTemplate)
	httpRouter.GET("/install/:id", api.ServeTemplate)
	httpRouter.POST("/install", api.InstallHandler)
	httpRouter.GET("/events/:id", api.EventsHandler)
	httpRouter.POST("/prompt/:id", api.PromptHandler)
	httpRouter.GET("/assets/*assetPath", api.ServeAsset)

	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return err
	}
	addr := fmt.Sprintf("http://localhost:%d", l.Addr().(*net.TCPAddr).Port)
	if err := api.OpenAddr(addr); err != nil {
		fmt.Printf("Open %s in your browser to continue.\n", addr)
	}
	return http.Serve(l, api.CorsHandler(httpRouter, addr))
}
Beispiel #3
0
func (c *AWSCluster) FindCredentials() (aws.CredentialsProvider, error) {
	if c.base.CredentialID == "aws_env" {
		return aws.EnvCreds()
	}
	cred, err := c.base.FindCredentials()
	if err != nil {
		return nil, err
	}
	return aws.Creds(cred.ID, cred.Secret, ""), nil
}
Beispiel #4
0
func amis(args *docopt.Args) {
	auth, err := aws.EnvCreds()
	if err != nil {
		log.Fatal(err)
	}

	manifest := &release.EC2Manifest{}

	if err := json.NewDecoder(os.Stdin).Decode(manifest); err != nil {
		log.Fatal(err)
	}

	for _, s := range strings.Split(args.String["<ids>"], ",") {
		regionID := strings.SplitN(s, ":", 2)
		svc := ec2.New(auth, regionID[0], nil)
		resp, err := svc.DescribeImages(&ec2.DescribeImagesRequest{ImageIDs: []string{regionID[1]}})
		if err != nil {
			log.Fatal(err)
		}
		if len(resp.Images) < 1 {
			log.Fatalln("Could not find image", regionID[1])
		}
		image := resp.Images[0]

		var snapshotID string
		for _, mapping := range image.BlockDeviceMappings {
			if *mapping.DeviceName == *image.RootDeviceName {
				snapshotID = *mapping.EBS.SnapshotID
			}
		}
		if snapshotID == "" {
			log.Fatalln("Could not determine RootDeviceSnapshotID for", regionID[1])
		}

		manifest.Add(args.String["<version>"], &release.EC2Image{
			ID:                   *image.ImageID,
			Name:                 *image.Name,
			Region:               regionID[0],
			OwnerID:              *image.OwnerID,
			RootDeviceType:       *image.RootDeviceType,
			RootDeviceName:       *image.RootDeviceName,
			RootDeviceSnapshotID: snapshotID,
			VirtualizationType:   *image.VirtualizationType,
			Hypervisor:           *image.Hypervisor,
		})

	}

	if err := json.NewEncoder(os.Stdout).Encode(manifest); err != nil {
		log.Fatal(err)
	}
}
Beispiel #5
0
func (api *httpAPI) InstallHandler(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
	var input *jsonInput
	if err := httphelper.DecodeJSON(req, &input); err != nil {
		httphelper.Error(w, err)
		return
	}
	api.InstallerStackMtx.Lock()
	defer api.InstallerStackMtx.Unlock()

	if len(api.InstallerStacks) > 0 {
		httphelper.ObjectExistsError(w, "install already started")
		return
	}

	var id = random.Hex(16)
	var creds aws.CredentialsProvider
	if input.Creds.AccessKeyID != "" && input.Creds.SecretAccessKey != "" {
		creds = aws.Creds(input.Creds.AccessKeyID, input.Creds.SecretAccessKey, "")
	} else {
		var err error
		creds, err = aws.EnvCreds()
		if err != nil {
			httphelper.ValidationError(w, "", err.Error())
			return
		}
	}
	s := &httpInstaller{
		ID:            id,
		PromptOutChan: make(chan *httpPrompt),
		PromptInChan:  make(chan *httpPrompt),
		logger:        log.New(),
		api:           api,
	}
	s.Stack = &Stack{
		Creds:        creds,
		Region:       input.Region,
		InstanceType: input.InstanceType,
		NumInstances: input.NumInstances,
		VpcCidr:      input.VpcCidr,
		SubnetCidr:   input.SubnetCidr,
		PromptInput:  s.PromptInput,
		YesNoPrompt:  s.YesNoPrompt,
	}
	if err := s.Stack.RunAWS(); err != nil {
		httphelper.Error(w, err)
		return
	}
	api.InstallerStacks[id] = s
	go s.handleEvents()
	httphelper.JSON(w, 200, s)
}
Beispiel #6
0
func (c *AWSCluster) SetCreds(creds *Credential) error {
	if creds == nil || creds.ID == "aws_env" {
		c.base.CredentialID = "aws_env"
		awsCreds, err := aws.EnvCreds()
		if err != nil {
			return err
		}
		c.creds = awsCreds
		return nil
	}
	c.base.credential = creds
	c.base.CredentialID = creds.ID
	c.creds = aws.Creds(creds.ID, creds.Secret, "")
	return nil
}
Beispiel #7
0
func (c *AWSCluster) SetCreds(creds *Credential) error {
	if creds == nil || creds.ID == "aws_env" {
		c.base.CredentialID = "aws_env"
		awsCreds, err := aws.EnvCreds()
		if err != nil {
			return err
		}
		c.creds = awsCreds
	} else {
		c.base.credential = creds
		c.base.CredentialID = creds.ID
		c.creds = aws.Creds(creds.ID, creds.Secret, "")
	}
	c.ec2 = ec2.New(c.creds, c.Region, nil)
	c.cf = cloudformation.New(c.creds, c.Region, nil)
	return nil
}
Beispiel #8
0
func (r *Runner) start() error {
	r.authKey = os.Getenv("AUTH_KEY")
	if r.authKey == "" {
		return errors.New("AUTH_KEY not set")
	}

	r.githubToken = os.Getenv("GITHUB_TOKEN")
	if r.githubToken == "" {
		return errors.New("GITHUB_TOKEN not set")
	}

	awsAuth, err := aws.EnvCreds()
	if err != nil {
		return err
	}
	r.s3 = s3.New(awsAuth, "us-east-1", nil)

	_, listenPort, err = net.SplitHostPort(args.ListenAddr)
	if err != nil {
		return err
	}

	bc := r.bc
	bc.Network = r.allocateNet()
	if r.rootFS, err = cluster.BuildFlynn(bc, args.RootFS, "origin/master", false, os.Stdout); err != nil {
		return fmt.Errorf("could not build flynn: %s", err)
	}
	r.releaseNet(bc.Network)
	shutdown.BeforeExit(func() { removeRootFS(r.rootFS) })

	db, err := bolt.Open(args.DBPath, 0600, &bolt.Options{Timeout: 5 * time.Second})
	if err != nil {
		return fmt.Errorf("could not open db: %s", err)
	}
	r.db = db
	shutdown.BeforeExit(func() { r.db.Close() })

	if err := r.db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists(dbBucket)
		return err
	}); err != nil {
		return fmt.Errorf("could not create builds bucket: %s", err)
	}

	for i := 0; i < args.ConcurrentBuilds; i++ {
		r.buildCh <- struct{}{}
	}

	if err := r.buildPending(); err != nil {
		log.Printf("could not build pending builds: %s", err)
	}

	go r.connectIRC()
	go r.watchEvents()

	router := httprouter.New()
	router.RedirectTrailingSlash = true
	router.Handler("GET", "/", http.RedirectHandler("/builds", 302))
	router.POST("/", r.handleEvent)
	router.GET("/builds/:build", r.getBuildLog)
	router.GET("/builds/:build/download", r.downloadBuildLog)
	router.POST("/builds/:build/restart", r.restartBuild)
	router.POST("/builds/:build/explain", r.explainBuild)
	router.GET("/builds", r.getBuilds)
	router.ServeFiles("/assets/*filepath", http.Dir(args.AssetsDir))
	router.GET("/cluster/:cluster", r.clusterAPI(r.getCluster))
	router.POST("/cluster/:cluster", r.clusterAPI(r.addHost))
	router.POST("/cluster/:cluster/release", r.clusterAPI(r.addReleaseHosts))
	router.DELETE("/cluster/:cluster/:host", r.clusterAPI(r.removeHost))

	srv := &http.Server{
		Addr:      args.ListenAddr,
		Handler:   router,
		TLSConfig: tlsconfig.SecureCiphers(nil),
	}
	log.Println("Listening on", args.ListenAddr, "...")
	if err := srv.ListenAndServeTLS(args.TLSCert, args.TLSKey); err != nil {
		return fmt.Errorf("ListenAndServeTLS: %s", err)
	}

	return nil
}